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

17

Я пишу хранимые 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
    
задан Chris Simpson 29.07.2010 в 20:13
источник

6 ответов

10

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

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

    
ответ дан swe 15.09.2015 в 14:28
источник
27

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

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

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)

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

    
ответ дан gbn 29.07.2010 в 20:19
источник
2

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

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   

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

ответ дан Andrew Jansen 18.10.2011 в 00:17
источник
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
)
    
ответ дан ensisNoctis 05.05.2016 в 11:08
источник
0

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

Declare @count int
set @count = 0

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

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

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

    
ответ дан AllenG 29.07.2010 в 20:17
источник
0

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

    
ответ дан JieLi 25.04.2014 в 20:09
источник