SQL Server 2005: оператор выбора в состоянии ISNULL - PullRequest
4 голосов
/ 18 июля 2010

Среда: SQL Server 2005

У меня есть сохраненный процесс, который получает значение через запятую в одном параметре.Я написал функцию UDF с табличным значением в SQL, чтобы разбить ее и вернуть мне в виде таблицы.Я использую это значение для фильтрации данных в предложении where хранимого процесса.Все работает нормально, пока в этой переменной, разделенной запятыми, не передается значение NULL, переданное хранимой процедуре.Я хочу написать мое предложение where таким образом, чтобы, если переданная переменная была NULL, она не должна использовать функцию Split.Вот что я делаю в сохраненной процедуре.

Declare @list varchar(100), @Col2 varchar(100)

SELECT  *
  FROM  Table1 t1
INNER JOIN dbo.Table2 t2 ON t1.Col1 = t2.Col1
WHERE t1.Col2 = ISNULL(@Col2,t1.Col2)
--I want to write below condition the same way i have written the above condition
    AND t1.Col3 IN (select * from dbo.SplitMe(@list))

Есть ли способ записать условие выбора Col3 способом, которым выбирается Col2?

Ответы [ 3 ]

2 голосов
/ 18 июля 2010

Если идея состоит в том, чтобы не фильтровать по Col3, если @list равно нулю, тогда вы могли бы сделать это так же

Declare @list varchar(100), @Col2 varchar(100)

SELECT  *
  FROM  Table1 t1
INNER JOIN dbo.Table2 t2
on t1.Col1 = t2.Col1

where t1.Col2 = ISNULL(@Col2,t1.Col2)
AND (@list IS NULL OR  t1.Col3 IN (select * from dbo.SplitMe(@list)))

, но это было бы не очень хорошоИдея, если таблицы очень маленькие.По причинам кэширования плана обычно лучше разбить все эти перестановки на их собственные операторы SQL, а не пытаться написать один размер, подходящий для всего запроса, или (если число перестановок становится слишком большим) рассмотреть возможность использования динамического SQL (см. DynamicУсловия поиска в T-SQL )

Обратите внимание, что не гарантирует, что функция Split не будет вызвана.Не существует гарантированного порядка оценки пунктов.Но это означает, что если он будет вызван, это не повлияет на результат запроса.( Редактировать при условии, конечно, что вызов, когда NULL на самом деле не вызывает какую-то ошибку, см. Комментарий Ремуса)

1 голос
/ 18 июля 2010
WHERE (t1.Col2 = @Col2 OR @Col2 IS NULL)
AND (t1.Col3 IN (select * from dbo.SplitMe(@list)) OR @list IS NULL)
1 голос
/ 18 июля 2010

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

Вы можете использовать оператор IF:

IF
BEGIN

    SELECT *
       FROM TABLE1 t1
       JOIN TABLE2 t2 ON t2.col1 = t1.col1
     WHERE t1.col1 = COALESCE(@col2, t1.col2)

END
ELSE
BEGIN

    SELECT *
       FROM TABLE1 t1
       JOIN TABLE2 t2 ON t2.col1 = t1.col1
      WHERE t1.col2 = COALESCE(@col2, t1.col2)
          AND t1.col3 IN (SELECT * FROM dbo.splitme(@list))

END

... но все еще есть нулевая обработка. Для двух переменных это четыре возможных значения результата. Ситуации, подобные этим, предназначены для динамического SQL - для создания запроса, необходимого, потому что при ручной клади багаж не работает.

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