Страница 1 из 1

Проблема с условием выбора

Добавлено: 23 дек 2007, 21:02
ostin
Помогите разобраться. Мне нужно выбрать из таблице записи с возможность отфильтровать ее по 4 полям или по 3, вообщем зависит от пользователя по каким параметрам ему нужно получит отчет, все поля не null.
Так я представляю себе эту процедуру так,

Код: Выделить всё

CREATE PROCEDURE new (
    a integer,
    b integer,
    c integer,
    d integer)
RETURNS (
    id INTEGER)
AS
BEGIN
for select id
 from table1
  where field1 = :a and field2 = :b and field3 = :c and field4 = :d
      into :id
  do
 suspend;
END
где может быть так
where field1 = 1 and field2 = 2 and field3 = 3 and field4 = 4
или так
where field1 is not null and field2 = 1 and field3 = 2 and field4 = 3
каким способом можно это реализовать.

Добавлено: 23 дек 2007, 23:04
kdv
а зачем для этого процедуру городить?

Добавлено: 24 дек 2007, 12:03
WildSery
Самое правильное решение тут - это формировать запрос динамически на клиенте по заданным условиям фильтра. И едиственное решение в случае большого числа фильтруемых записей.

Есть ещё путь, но это только когда некуда деваться, а именно
where (Field1 is null or Field1 = :a) and (Field2 is null or Field2 = :b) ...
Это позволит отключить фильтр по полю, если передать в параметр null.
Однако, если записей не 100, то производительность упадёт катастрофически (индексы не используются для отбора по таким условиям), выборка 1 записи, попадающей под условия, будет выполняться столько же, сколько целиком выборка без условий.

Добавлено: 24 дек 2007, 12:59
Кузнецов Евгений
WildSery писал(а): Самое правильное решение тут - это формировать запрос динамически на клиенте по заданным условиям фильтра. И едиственное решение в случае большого числа фильтруемых записей.
В FB 2 можно выкрутиться через IS NOT DISTINCT FROM

Добавлено: 24 дек 2007, 13:31
WildSery
Кузнецов Евгений писал(а):В FB 2 можно выкрутиться через IS NOT DISTINCT FROM
Что-то не могу сообразить, какое должно быть условие.
Ведь если параметр будет NULL, то и найдены будут только значения NULL?

Добавлено: 24 дек 2007, 14:58
Кузнецов Евгений
WildSery писал(а): Ведь если параметр будет NULL, то и найдены будут только значения NULL?
Стормозил, каюсь - IS DISTINCT ничем не поможет.

Единственное замечание - для
WildSery писал(а): where (Field1 is null or Field1 = :a) and (Field2 is null or Field2 = :b) ...
индексы всё же могут использоваться.

Добавлено: 24 дек 2007, 15:40
WildSery
Кузнецов Евгений писал(а):индексы всё же могут использоваться.
Это каким образом?

Добавлено: 24 дек 2007, 16:12
Кузнецов Евгений
WildSery писал(а):Это каким образом?
Ну для

Код: Выделить всё

select * from test_table2
where  (Field1 is null or Field1 = :a) and
(Field2 is null or Field2 = :a)
план следующий

Код: Выделить всё

PLAN (TEST_TABLE2 INDEX (TEST_W2, TEST_W2, TEST_W1, TEST_W1))
Test_w1 - индекс по Field1
Test_w2 - индекс по Field2

Добавлено: 24 дек 2007, 17:09
DMA
А может так: select * from test_table2
where (Field1 = :a or :a is null) and
(Field2 = :b or :b is null) and
(Field3 = :c or :c is null) and
(Field4 = :d or :d is null)

Добавлено: 24 дек 2007, 17:16
WildSery
Тьфу ты, точно.
Прошу прощения, это я пример неправильный изначально написал, и больше на него не смотрел, и получается что гоню ерунду.
На самом деле, я хотел написать

Код: Выделить всё

where  (cast(:a as int) is null or Field1 = :a) and (cast(:b as int) or Field2 = :b)
Вариант без каста прокатит в случае процедуры, где тип параметра явно определён.

Добавлено: 26 дек 2007, 19:51
ostin
Спасибо всем кто ответил мне. прочитав все я буду искать наилучшие вариант решения моей проблемы. Спасибо еще раз