Проблема с оператором SQL - PullRequest
2 голосов
/ 08 декабря 2008

У меня есть этот код:

SELECT    idcallhistory3, callid, starttime, answertime, endtime, duration,
          is_answ, is_fail, is_compl, is_fromoutside, mediatype, from_no,
          to_no, callerid, dialednumber, lastcallerid, lastdialednumber,
          group_no, line_no
FROM      "public".callhistory3
WHERE     (starttime >= ?) AND (endtime <= ?) AND (is_fromoutside = ?) 
          AND (from_no = ?) AND (to_no = ?)

Проблема в том, что мне нужно передать одно значение для? и получить весь результат без фильтра, что-то вроде *

Любая помощь?

Ответы [ 6 ]

7 голосов
/ 08 декабря 2008
WHERE 
  (@start is null OR starttime >= @start) AND 
  (@end is null OR endtime <= @end) AND 
  (@fromOutside is null OR is_fromoutside = @fromOutside) AND 
  (@fromNo is null OR from_no = @fromNo) AND 
  (@toNo is null OR to_no = @toNo)

Передать нули для всех параметров (dang sql nulls; спасибо GC).

3 голосов
/ 08 декабря 2008

Мне нравится COALESCE.

Вам просто нужно быть осторожным с нулевыми значениями в левой части, если в левой части могут быть нулевые значения, вы можете сделать что-то вроде последней строки, чтобы нулевые значения совпадали. Как правило, с чем-то вроде этого, хотя вы хотите убедиться, что ваш запрос по-прежнему работает нормально.

SELECT    idcallhistory3, callid, starttime, answertime, endtime, duration,
          is_answ, is_fail, is_compl, is_fromoutside, mediatype, from_no,
          to_no, callerid, dialednumber, lastcallerid, lastdialednumber,
          group_no, line_no
FROM      "public".callhistory3
WHERE     (starttime >= COALESCE(@starttime, starttime )) 
          AND (endtime <= COALESCE(@endtime, endtime)) 
          AND (is_fromoutside = COALESCE(@is_fromoutside, is_fromoutside)) 
          AND (from_no = COALESCE(@from_no, from_no)) 
          AND (COALESCE(to_no, -1) = COALESCE(@to_no, to_no, -1)) -- make nulls match
2 голосов
/ 08 декабря 2008

Для сложных запросов с несколькими необязательными секциями вы можете обнаружить, что лучше создать SQL, который вам подойдет. Вы можете сделать это либо в вызывающей программе (например, в C #), либо в базе данных (по крайней мере, в SQL Server) - но в любом случае вы должны убедиться, что она остается параметризованной. Когда вызывающая сторона выполняет работу, это всего лишь случай добавления подходящих параметров в команду. Если БД генерирует TSQL, то подход зависит от СУБД. С SQL-сервером sp_ExecuteSql - ваш друг, то есть вы можете создать переменную @cmd на основе запроса, тогда:

EXEC sp_ExecuteSQL @cmd, N'@someArg int', @actualArg

Где @someArg - объявление внутри @cmd, а @actualArg - значение, которое передается во время выполнения.

1 голос
/ 08 декабря 2008

Добавьте оператор «Где» условно - только если вам нужно отфильтровать результаты

1 голос
/ 08 декабря 2008

Типичный способ сделать это что-то вроде:

WHERE (? IS NULL OR starttime >= ?)

, а затем передать в DBNull.Value. Очевидно, вам нужно сделать это для каждого параметра, который вы хотите использовать для «подстановочных знаков», подобных этому.

0 голосов
/ 08 декабря 2008

Я согласен с Джамалом Хансеном. COALESCE - безусловно, самый эффективный способ, по крайней мере, для SQL Server

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...