Подтвердить что ты не робот

Добавить пустую строку для запроса результатов, если результатов не найдено

Я пишу хранимые procs, которые вызываются унаследованной системой. Одним из ограничений устаревшей системы является то, что в едином результирующем наборе, возвращаемом из сохраненного процесса, должна быть хотя бы одна строка. Стандарт должен вернуть ноль в первом столбце (да, я знаю!).

Очевидный способ добиться этого - создать временную таблицу, поместить в нее результаты, протестировать любые строки в таблице temp и либо вернуть результаты из таблицы temp, либо один пустой результат.

Другим способом может быть выполнение EXISTS против того же предложения where, что и в основном запросе до выполнения основного запроса.

Ни одно из них не очень удовлетворительно. Может ли кто-нибудь подумать о лучшем пути. Я думал о таких типах UNION вроде этого (я знаю, что это не работает):

--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
4b9b3361

Ответ 1

Это старый вопрос, но у меня была такая же проблема. Решение действительно просто БЕЗ двойного выбора:

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", поэтому все являются связями), или если результата нет, вы получаете свое значение по умолчанию.

Ответ 2

Очень мало вариантов, которых я боюсь.

Вы всегда должны прикоснуться к таблице дважды, будь то COUNT, EXISTS before, EXISTs в разделе UNION, TOP и т.д.

select
    id, category
from mytable
where category = @category
union all --edit, of course it quicker
select
    0, ''
where NOT EXISTS (SELECT * FROM mytable where category = @category)

Решение EXISTS лучше, чем COUNT, потому что оно остановится, когда найдет строку. COUNT будет пересекать все строки, чтобы их действительно считать

Ответ 3

Вы можете использовать полное внешнее соединение. Что-то из-за...

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   

В настоящее время, тестируя этот сценарий, я не уверен, какое влияние это будет иметь, но это даст вам пустую строку с заполненной категорией.

Ответ 4

Это ответ @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'[email protected]', NULL, NULL, 2),
            (N'[email protected]', NULL, NULL, 2)
        ) defaults([To], CC, BCC, Priority)
    ) emails
    ORDER BY Priority
)

Ответ 5

Я думаю, вы могли бы попробовать:

Declare @count int
set @count = 0

Begin
Select @count = Count([Column])
From //Your query

if(@Count = 0) 
   select 0
else //run your query

Недостатком является то, что вы эффективно выполняете свой запрос дважды, а вверху - то, что вы пропускаете таблицу temp.

Ответ 6

Чтобы избежать дублирования запроса выбора, как насчет таблицы temp для сохранения результата запроса? И на основе временной таблицы возвращайте строку по умолчанию, если таблица temp пуста или возвращает temp, когда она имеет результат?