sql - 当 tvp 不包含任何行时,带有输入 tvp 参数的单个 SQL 查询

标签 sql sql-server stored-procedures table-valued-parameters

任何人都知道这种技巧

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

因此,上面的过程返回单个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

有没有办法将带有tvp输入参数SP代码更改为单个查询?

最佳答案

您可以使用 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 会在第一次调用存储过程时编译查询。并且查询计划可能并非对于所有参数选择都是最佳的。

关于sql - 当 tvp 不包含任何行时,带有输入 tvp 参数的单个 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36452853/

相关文章:

c# - 获取父级菜单的所有子级详细信息

sql - 需要查询帮助

sql - 哪里使用SQL的列级加密?

mysql - 不能只显示多个交易的最大日期

vba - 在 Access 中使用 SQL Server 存储过程的输出参数

mysql - 将重音符号传递给 mysql 存储过程时出现问题

使用 % 和 LIKE 在 Rails 中进行 SQL 查询

c# - 使用 IIS6 将 C# Web 应用程序添加到网站

mysql - 在从游标获取数据的循环中更新游标的查询表是否合法

sql - 从函数返回查询?