T SQL Условное объединение на основе значения параметра - PullRequest
1 голос
/ 06 февраля 2012

Мне нужно внутреннее соединение, основанное на значении параметра, который у меня есть в хранимой процедуре.Я также использую функцию для разделения значений из строки значений, разделенных запятыми.Мой код выглядит следующим образом:

Select *
from view_Project as vp
join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)

Если @earmark равен NULL, тогда я не хочу, чтобы это соединение вообще происходило, в противном случае, если у меня есть строка '%' или '119' или '119,120,121'это объединение должно произойти и дает правильные результаты.Я просто хотел бы, чтобы это вообще не происходило, если @earmark равен нулю, я подумал, что могу просто использовать и @earmark не равен нулю, чтобы обозначить, что, однако, он не возвращает правильные результаты, которые обнаруживаются при комментировании объединенияline и запускает тот же sproc со значением null, что и параметр @earmark, что дает мне все строки в результате.Когда я сохраняю это соединение и пропускаю ноль, я не получаю строк, я возился с этим в течение некоторого времени, любая помощь будет оценена.

Вот ФУНКЦИЯ:

[inline_split_me](@param nvarchar(MAX))
RETURNS TABLE AS
RETURN(SELECT ltrim(rtrim(convert(nvarchar(4000),
    substring(@param, Number,
        charindex(N',' COLLATE SQL_Latin1_General_CP1_CI_AS,
        @param + convert(nvarchar(MAX), N','),
    Number) -
Number)
))) AS Value
   FROM   APM_Numbers
   WHERE  Number <= convert(int, len(@param))
     AND  substring(convert(nvarchar(MAX), N',') + @param, Number, 1) =
                    N',' COLLATE SQL_Latin1_General_CP1_CI_AS)

Понял, спасибо Кейд Ру и другим

if (@earmark = '%')
select *
    from view_Project as vp
    where vp.EarmarkId like @earmark
else
select *
    from view_Project as vp
    where @earmark is null or vp.EarmarkId in (select Value from inline_split_me(@earmark))

Ответы [ 2 ]

4 голосов
/ 06 февраля 2012

ВНУТРЕННЕЕ СОЕДИНЕНИЕ - ваша проблема.LEFT JOIN всегда будет возвращать строки в LEFT, даже если @earmark равен NULL, условие соединения никогда не может быть истинным.

Select *
from view_Project as vp
LEFT join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)

Вы можете пошалить с UNION, чтобы создавать строки для объединения, когда@earmark равен NULL

Select *
from view_Project as vp
INNER join (
    SELECT Value, -- columns here ...
    FROM inline_split_me(@earmark) as e
    UNION ALL
    SELECT DISTINCT vp.EarmarkId AS Value, -- NULL, NULL, etc.
    FROM view_Project
    WHERE @earmark IS NULL
) AS e
    ON vp.EarmarkId LIKE e.Value

Но, честно говоря, я бы просто сделал условную логику:

IF @earmark IS NULL
    Select *
    from view_Project as vp
ELSE
    Select *
    from view_Project as vp
    INNER join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)

Если вы можете отойти от LIKE:

Select *
from view_Project as vp
WHERE @earmark IS NULL OR vp.EarmarkId IN (
    SELECT Value FROM inline_split_me(@earmark)
)
0 голосов
/ 06 февраля 2012

...as vp join lined_split_me(@earmark) as... по умолчанию должно использоваться внутреннее соединение, что означает, что запрос возвращает строки только в том случае, если между двумя таблицами найдены совпадения. (Дважды проверьте, явно сказав inner join.)

Возвращает ли вызов функции (ноль) строк, если @earmark равен нулю? Если это так, то в запросе не должно быть никаких строк.

...