SQL: как сделать проверку IF для параметров диапазона данных - PullRequest
0 голосов
/ 20 декабря 2018

Я пишу хранимую процедуру, которая принимает 4 параметра: номер_подтверждения, номер_платы, начальный_предел, диапазон_ конечных.

Параметры являются необязательными, поэтому я проверяю таким образом номер подтверждения и номер_платыпараметры:

IF (@s_Confirmation_Number IS NOT NULL) 
SET @SQL = @SQL + ' AND pd.TransactionNumber = @s_Confirmation_Number'

IF (@d_Payment_Amount IS NOT NULL) 
SET @SQL = @SQL + ' AND pd.PaymentAmount = @d_Payment_Amount'

Я хотел бы попросить о помощи, потому что я не уверен, что является лучшим методом для проверки параметров диапазона дат.

Если бы кто-нибудь мог привести мне пример или несколько примеров того, как это лучше всего сделать, это было бы здорово.

Заранее спасибо.

ОБНОВЛЕНИЕ - после получения некоторой большой помощи -.

Это то, что я имею до сих пор, я следую рекомендациям scsimon, но я не уверен насчет дат, я получил идею из другого поста, который нашел, и немного игралвокруг с этим.Не могли бы вы посмотреть на это и сказать, что вы все думаете?

Большое спасибо.

    @s_Confirmation_Number  NVARCHAR(50) = NULL
,   @d_Payment_Amount       DECIMAL(18, 2) = NULL
,   @d_Start_Range          DATE = NULL
,   @d_End_Range            DATE = NULL
...
....

WHERE
    ph.SourceType = @s_Source_Type
    AND ((pd.TransConfirmID = @s_Confirmation_Number) OR @s_Confirmation_Number IS NULL)            
    AND ((pd.PaymentAmount = @d_Payment_Amount) OR @d_Payment_Amount IS NULL)
    AND (((NULLIF(@d_Start_Range, '') IS NULL) OR CAST(pd.CreatedDate AS DATE) >= @d_Start_Range)
    AND ((NULLIF(@d_End_Range, '') IS NULL) OR CAST(pd.CreatedDate AS DATE) <= @d_End_Range))

(параметр sourceType является жестко заданным значением)

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Я делаю это следующим образом

 WHERE 
    COALESCE(@s_Confirmation_Number,pd.TransactionNumber) = pd.TransactionNumber AND
    COALESCE(@d_Payment_Amount,pd.PaymentAmount) = pd.PaymentAmount 

Если у нас есть значение для каждого из этих параметров, то оно будет сверяться со значением фильтра, в противном случае оно всегда будет соответствовать значению фильтра, если параметр равен нулю.

Я обнаружил, что использование COALESCE быстрее и понятнее, чем операторы управления IF или использование OR в предложении WHERE.

0 голосов
/ 21 декабря 2018

Есть другой способ.Но я протестировал и понял, что запрос scsimon быстрее, чем мой.

AND (CASE 
    WHEN @Confirmation_Number is not null 
        THEN (CASE 
            WHEN pd.TransactionNumber = @Confirmation_Number 
                THEN 1
            ELSE 0
        END)
    ELSE 1
END = 1)
0 голосов
/ 21 декабря 2018

Это называется запросить все или кухонная раковина запрос.Обычно записывается так:

create procedure myProc
   (@Payment_Amount int = null     
   ,@Confirmation_Number  = null
   ,@start_range datetime
   ,@end_range datetime)

as

select ...
from ...
where 
    (pd.TransactionNumber = @Confirmation_Number or @Confirmation_Number is null)
and (pd.PaymentAmount = @Payment_Amount or @Payment_Amount is null)

NULL для двух параметров дает им значение по умолчанию NULL и делает их "необязательными".Предложение WHERE оценивает это, чтобы возвращать только те строки, в которых ваш пользовательский ввод соответствует значению столбца, или все строки, когда пользовательский ввод не был предоставлен (т. Е. Параметр IS NULL). Вы также можете использовать это с параметрами даты .Просто обратите пристальное внимание на ваши скобки.Они имеют значение очень много здесь, потому что мы смешиваем and и or логику.

Аарон Бертран широко об этом писал.

...