Добавьте пустую строку в результаты запроса, если результаты не найдены
Я пишу хранимые procs, которые вызываются устаревшей системой. Одно из ограничений устаревшей системы заключается в том, что в одном результирующем наборе, возвращаемом из сохраненного процесса, должна быть по крайней мере одна строка. Стандарт состоит в том, чтобы вернуть ноль в первом столбце (да, я знаю!).
Очевидный способ достичь этого-создать временную таблицу, поместить в нее результаты, проверить все строки В временной таблице и либо вернуть результаты из временной таблицы, либо один пустой результат.
Другой способ может заключаться в том, чтобы сделать EXISTS против того же предложения where, которое находится в основном запросе до выполнения основного запроса.
Ни то, ни другое не приносит большого удовлетворения. Может ли кто-нибудь придумать лучший способ. Я думал о таких союзах, как этот (я знаю, что это не работает):--create table #test
--(
-- id int identity,
-- category varchar(10)
--)
--go
--insert #test values ('A')
--insert #test values ('B')
--insert #test values ('C')
declare @category varchar(10)
set @category = 'D'
select
id, category
from #test
where category = @category
union
select
0, ''
from #test
where @@rowcount = 0
6 ответов:
Это старый вопрос, но у меня была та же проблема. Решение действительно простое без двойного выбора:
select top(1) WITH TIES * FROM ( select id, category, 1 as orderdummy from #test where category = @category union select 0, '', 2) ORDER BY orderdummy
С помощью "WITH TIES "вы получаете все строки (все имеют 1 Как" orderdummy", поэтому все являются связями), или если нет результата, вы получаете свой defaultrow.
Боюсь, что вариантов очень мало.
Вы всегда должны коснуться таблицы дважды, будь то COUNT, EXISTS before, EXISTs in UNION, TOP clause и т. д.
select id, category from mytable where category = @category union all --edit, of course it's quicker select 0, '' where NOT EXISTS (SELECT * FROM mytable where category = @category)
Существующее решение лучше, чем считать, потому что оно остановится, когда найдет строку. Подсчет будет проходить все строки, чтобы их сосчитать
Вы можете использовать полное внешнее соединение. Что-то в этом роде...
declare @category varchar(10) set @category = 'D' select #test.id, ISNULL(#test.category, @category) as category from ( select id, category from #test where category = @category ) FULL OUTER JOIN (Select @category as CategoryHelper ) as EmptyHelper on 1=1
В настоящее время я сам тестирую этот сценарий, поэтому не уверен, какое влияние это окажет, но это даст вам пустую строку с заполненной категорией.
Это ответ @swe, только отформатированный лучше.
CREATE FUNCTION [mail].[f_GetRecipients] ( @MailContentCode VARCHAR(50) ) RETURNS TABLE AS RETURN ( SELECT TOP 1 WITH TIES -- returns all rows having highest priority found [To], CC, BCC FROM ( SELECT [To], CC, BCC, 1 AS Priority -- if no rows, priority 2 under UNION will get returned FROM mail.Recipients WHERE 1 = 1 AND IsActive = 1 AND MailContentCode = @MailContentCode UNION ALL SELECT * FROM (VALUES (N'system@company.com', NULL, NULL, 2), (N'author@company.com', NULL, NULL, 2) ) defaults([To], CC, BCC, Priority) ) emails ORDER BY Priority )
Я думаю, вы могли бы попробовать:
Declare @count int set @count = 0 Begin Select @count = Count([Column]) From //Your query if(@Count = 0) select 0 else //run your query
Недостатком является то, что вы эффективно выполняете запрос дважды, а недостатком является то, что вы пропускаете временную таблицу.