Переменное число критериев отбора в запросе
Переменное число критериев отбора в запросе
Здравствуйте! Необходимо написать процедуру для выборки данных, в которой некоторые критерии отбора не принимались бы во внимание, если пользователь не ввел для них значения. Наверняка кто-то сталкивался с такой задачей. Какие использовали решения? Спасибо.
Re: Переменное число критериев отбора в запросе
Если критериев фиксированное кол-во и надо именно просто не принимать некоторые из них во внимание, если значение не указано, то можно сделать примерно так:irq писал(а):Здравствуйте! Необходимо написать процедуру для выборки данных, в которой некоторые критерии отбора не принимались бы во внимание, если пользователь не ввел для них значения. Наверняка кто-то сталкивался с такой задачей. Какие использовали решения? Спасибо.
Код: Выделить всё
select ...
...
where (:Param1 is NULL or Field1=:Param1) and
(:Param2 is NULL or Field2=:Param2) and
...
Не хочется писать не нужный код размером в несколько страниц. Но если в interbase нет других способов, кроме этого...kdv писал(а):то есть, не хочется писать код?![]()
а как же оптимизация? планов-то в этом случае не будетkdv писал(а): пишется код, динамически подставляются условия where. на сервер уходит готовый запрос. красивость и компактность зависит от умения программировать на pascal, c++ и т.п.
в смысле - в sql этот вопрос решаем одним движением пальца? оригинально. задача состоит в динамическом формировании запроса, ничего здесь страшного нет и тем более нет никакого "кода размером в несколько страниц".Не хочется писать не нужный код размером в несколько страниц. Но если в interbase нет других способов, кроме этого...
гм, каких-таких планов??? оптимизатор сам построит нужный план, как обычно. или вы всем своим запросам планы вручную добавляете?а как же оптимизация? планов-то в этом случае не будет
кстати, пример jake - (:Param1 is NULL or Field1=:Param1) не рекомендую. тут вообще ни о каких индексах не может быть и речи, и при условиях отбора например с 5-ти и опр. количестве записей будут просто тормоза, и ничего более. поэтому настоятельно советую именно динамическое формирование клиентом текста where. есть условие - добавляем к where. нет условия - не добавляем.
Да, про проблемы с использованием индексов я тоже написал. Но например в случае хр. процедуры, зачастую, это может оказаться лучшим решением чемkdv писал(а):кстати, пример jake - (:Param1 is NULL or Field1=:Param1) не рекомендую. тут вообще ни о каких индексах не может быть и речи, и при условиях отбора например с 5-ти и опр. количестве записей будут просто тормоза, и ничего более. поэтому настоятельно советую именно динамическое формирование клиентом текста where. есть условие - добавляем к where. нет условия - не добавляем.
select ... from StoredProc where....
при разумном использовании (:Param1 is NULL or Field1=:Param1) внутри процедуры конечно.
Кстати в MSSQL при таком "финте" с OR индексы все равно используются, когда это нужно. Дмитрий, Вы не в курсе, эта проблема будет решена в FB2? Или внутренняя архитектура IB/FB этого вообще не позволяет?
(:Param1 is NULL or Field1=:Param1)
если :param1 is null, то индекс не нужен, наоборот, он будет мешать.
если :param1 is not null, то индекс нужен.
кроме того, условие :param1 is null не по столбцу. конечно, если предположить, что данное условие с or используется исключительно для таких вот "выкрутасов", то теоретически можно ковырнуть оптимизатор, чтобы он игнорировал часть ":Param1 is NULL or".
как там будет с этим в FB2, пока не знаю.
если :param1 is null, то индекс не нужен, наоборот, он будет мешать.
если :param1 is not null, то индекс нужен.
кроме того, условие :param1 is null не по столбцу. конечно, если предположить, что данное условие с or используется исключительно для таких вот "выкрутасов", то теоретически можно ковырнуть оптимизатор, чтобы он игнорировал часть ":Param1 is NULL or".
как там будет с этим в FB2, пока не знаю.
Re: Переменное число критериев отбора в запросе
В Firebird 1.5 есть такая конструкция:irq писал(а):Необходимо написать процедуру для выборки данных, в которой некоторые критерии отбора не принимались бы во внимание
EXECUTE STATEMENT <string>;
FOR EXECUTE STATEMENT <string> INTO :var1, ., :varn DO
<compound-statement>;
Sample:
CREATE PROCEDURE DynamicSampleThree (TextField VARCHAR(100), TableName VARCHAR(100))
RETURNING_VALUES (Line VARCHAR(32000))
AS
DECLARE VARIABLE OneLine VARCHAR(100);
BEGIN
Line = '';
FOR EXECUTE STATEMENT 'SELECT ' || TextField || ' FROM ' || TableName
INTO :OneLine
DO
IF (OneLine IS NOT NULL) THEN
Line = Line || OneLine || ' ';
SUSPEND;
END