Методика построения запроса
От: Аноним  
Дата: 16.06.09 13:40
Оценка:
День добрый.
Задача: надо придумать универсальный механизм, который будет строить SQL запросы, на вход которому будут подаваться поля и критерии отбора объектов. Должна поддерживаться вложенность полей и критериев.

Пример.

Для простоты пусть будет одна древовидная таблица TestTable(Id, ParentId, Name).


Надо выбрать все поля всех записей, у которых Name = 'Раз', но при этом есть дочерние записи у которых Name = 'Два' (тоже все поля), у которых есть дочерние, к которых Name = 'Три' (но тут, например, выбрать только поле Name и Id).

Механизм должен быть универсальным и выполняться одним запросом.
Пока пришло в голову использовать запрос вида:

select t1.*,
             (select t4.*,
                             (select t5.Id,
                                             t5.Name
                                from TestTable t5
                                where t5.Id = t4.Id
                                for xml auto, type)
                from TestTable t4
                where t4.Id = t1.ParentId
                for xml auto, type)
from TestTable t1
where t1.Name = 'Раз'
and exists (select t2.Id
             from TestTable t2
             where t2.Id = t1.ParentId
             and t2.Name = 'Два'
             and exists (select t3.Id
                            from TestTable t3
                            where t3.Id = t2.Id
                            and t3.Name = 'Три'))
for xml auto, type


Интересует кривизна (в SQL я не силен) и производительность данного варианта (при грамотно настроенных индексах).

MS SQL Server 2005/2008.

Спасибо.
Re: Методика построения запроса
От: MasterZiv СССР  
Дата: 16.06.09 14:19
Оценка:
Аноним 95 wrote:

> Задача: надо придумать универсальный механизм, который будет строить SQL

> запросы, на вход которому будут подаваться поля и критерии отбора
> объектов. Должна поддерживаться вложенность полей и критериев.

Универсальные запросы -- это плохие запросы.
В общем запросы либо НЕ универсальные, либо НЕ работают.
Posted via RSDN NNTP Server 2.1 beta
Re: Методика построения запроса
От: Neco  
Дата: 17.06.09 05:15
Оценка:
А>Задача: надо придумать универсальный механизм, который будет строить SQL запросы
А>Для простоты пусть будет одна древовидная таблица TestTable(Id, ParentId, Name).
мехнизмы с универсальностью в рамках одной системы приходилось делать, но чтобы прям ваааапще универсально — как-то нереально.
тот же пример, который вы взяли для простоты — при таких запросах (когда надо проверять дочерние от дочерних) я не стал бы использовать такой способ хранения дерева (лучше правое-левое плечо или транзитивное замыкание), следовательно универсальный механизм по отношению к моим древовидным структурам уже будет должен строить другой запрос.

ту универсальность, которую я себе устраивал, заключалась в следующем (шаблон Builder по-моему): разбиваем БД на сущности (в самом простом случае одна сущность — одна таблица, но иногда и посложнее), описываем в виде классов, которые знают специфику своих сущностей (в каких таблицах хранятся и как эти таблицы между собой компонуются, какие хинты когда применять). Сверху ряд классов для группировки сущностей и для группировок групп. Каждый класс умеет: строить свою часть sql-запроса и анализировать критерии для выяснения какое поле нужно "выталкивать" наверх. Далее в нужном месте начинаем склеивать эти классы вместе, передавать им критерии и получать от них sql-запросы.

на деле выходит, что написать всё это уже долго, а писать запросы в терминах своих сущностей не всегда удобно и понятно (sql как-то ближе всё-таки) — но это смотря как писать, если толково подойти, то выйдет проще, наверное.
но у меня на входе было порядка десяти критериев, а у каждого их них в среднем по четыре значения — итого 400 больших, сильно и не очень различающихся запросов. Универсальность показалась выгодной, вот и применил. Но в каждом конкретном случае надо смотреть отдельно — иногда, думаю, проще сгруппировать сходные запросы и уже в их рамках управлять фильтрами и колонками.
всю ночь не ем, весь день не сплю — устаю
Re: Методика построения запроса
От: Azec http://najdi-sebja.ru
Дата: 17.06.09 20:53
Оценка:
на Linq такой запрос будет выглядить очень коротко, в чистом SQL полагаю, тоже но думать неохода.

.Where(x.Name=="три" && x.Parent!=null && x.Parent.Name=="Два" && x.PArent.Parent!=null && x.PArent.PArent == "раз")

вот и готово.
Re: Методика построения запроса
От: MozgC США http://nightcoder.livejournal.com
Дата: 17.06.09 21:16
Оценка:
Вы пытаетесь создать велосипед.
Может быть стоит воспользовать какими-либо готовыми решениями генерирующими SQL на выходе? Ну к примеру в случае если пишете на .NET, то типа Linq2Sql/SubSonic/NHibernate и т.д.?
По какими причинам вы хотите сделать свой велосипед?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.