Мне бы хотелось сделать что-то как следующее в SQL-сервере 2005 (который я знаю, не допустимо) для моего, где пункт. Иногда @teamID (передал в хранимую процедуру) будет значением существующего teamID, иначе это всегда будет нуль, и я хочу все строки от таблицы Team.
Я исследовал Случай использования, и оператор должен прибыть прежде или после всего оператора, который препятствует тому, чтобы я имел другой оператор на основе значения @teamid. Любые предложения кроме дублирования моих избранных операторов.
declare @teamid int
set @teamid = 0
Select Team.teamID From Team
case @teamid
when 0 then
WHERE Team.teamID > 0
else
WHERE Team.teamID = @teamid
end
Вы можете сделать это без дела:
SELECT Team.teamID
FROM Team
WHERE (@teamid = 0 AND Team.teamID > 0)
OR (@teamid <> 0 AND Team.teamID = @teamid)
Если бы вы могли рассматривать Null как все записи:
WHERE Team.teamID = ISNULL(@teamid, Team.teamID)
А как насчет:
Select Team.teamID From Team Where (@teamid=0 and team.teamID>0) or (@teamid<>0 and team.teamid=@teamid)
Даже проще, чем ответ Андомара, и если предположить, что id никогда не равен 0 (как для большинства идентификаторов с автоматическим увеличением), это
SELECT Team.teamID
FROM Team
WHERE @teamid = 0 or Team.teamID = @teamid;
Этот предикат всегда истинен, когда @teamid равен нулю, в противном случае - истина только тогда, когда он соответствует teamId конкретной строки.
Однако обратите внимание: это довольно эффективно работает на Sybase 11 или выше; он работал довольно неэффективно на MS SQL server 2003; Я не знаю, как это работает в текущей версии MS SQL Server.
Также вы можете использовать case; вам просто нужно указать случай в предложении where, а не в предложении where в случае. Итак, ваш исходный запрос будет выглядеть так:
Select Team.teamID
From Team
where
case when @teamid = 0 then 0 else Team.teamID end = @teamId;
Обратите внимание, что это, вероятно, будет менее эффективным, поскольку он должен оцениваться для каждой строки и также, вероятно, приведет к полному сканированию таблицы.
Форма, которую я дал выше, с большей вероятностью будет переписана интеллектуальным оптимизатором запросов (ваш опыт зависит от вашей СУБД), чтобы использовать индекс, когда @teamid не равно нулю.
Без использования динамического SQL наиболее эффективный вариант:
IF @teamid = 0
BEGIN
SELECT t.teamid
FROM TEAM t
WHERE t.teamid > 0
END
ELSE
BEGIN
SELECT t.teamid
FROM TEAM t
WHERE t.teamid = @teamid
END
Использование динамического SQL:
DECLARE @SQL NVARCHAR(4000)
SET @SQL = 'SELECT t.teamid
FROM TEAM t
WHERE 1 = 1 '
SET @SQL = @SQL + CASE @teamid
WHEN 0 THEN ' AND t.teamid > 0 '
ELSE ' AND t.teamid = @teamid '
END
BEGIN
EXEC sp_EXECUTESQL @SQL N'@teamid INT', @teamid
END
Помните, что sp_EXECUTESQL
кэширует план запроса, а EXEC - нет. Прочтите это: http://www.sommarskog.se/dynamic_sql.html