Один SQL-запрос с входным параметром tvp, когда tvp не содержит ни одной строки

Кто-нибудь знает вид этого трюка

CREATE PROCEDURE [pr_GetFinDoc]
    @id UNIQUEIDENTIFIER NULL
AS
BEGIN
    SELECT f.*
    FROM [dbo].[FinDocument] f     --id column is primary key
    WHERE @id is null or f.id = @id
END

Итак procedure выше возвращает либо один FinDoc или все FinDocs, Это зависит от того, id был отправлен или нет.

Просто один запрос.

Так что мне нужно что-то подобное, но для tvp параметр.

Это мой tvp параметр - просто массив uniqueidentifier ценности

CREATE TYPE [dbo].[GuidList] AS TABLE(
    [Id] [uniqueidentifier] NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)

И моя хранимая процедура:

CREATE PROCEDURE [pr_GetFinDoc]
    @id_list [dbo].[GuidList] READONLY
AS
BEGIN

    IF EXISTS (SELECT 1 FROM @id_list)
        BEGIN
            SELECT f.*
            FROM
            @id_list filter 
                INNER JOIN [dbo].[FinDocument] f 
                    ON f.id = filter.Id
        END
    ELSE
        BEGIN
            SELECT f.*
            FROM [dbo].[FinDocument] f
        END
END

Есть ли способ изменить код SP с tvp input parameter на один запрос?

1 ответ

Решение

Ты можешь использовать IN вместо. Это дает вам гибкость в использовании более сложной логики:

select f.*
from FinDocument f
where f.id in (select id from @id_list) or
      not exists (select 1 from @id_list);

Обратите внимание, что эти методы (и ваши) не обязательно эффективны. if логика, вероятно, скомпилируется с использованием индекса на id, Часто, если запросы сложны, лучше либо принудительно перекомпилировать, либо использовать динамический SQL (и принудительно перекомпилировать), поскольку SQL Server компилирует запросы при первом вызове хранимой процедуры. И план запроса может быть не оптимальным для всех вариантов выбора.

Другие вопросы по тегам