使用临时表时,描述第一个结果集的SQL Server失败(sp_describe_first_result_set)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用临时表时,描述第一个结果集的SQL Server失败(sp_describe_first_result_set)相关的知识,希望对你有一定的参考价值。

长话短说,我有一个第三方应用程序,当它无法检索查询/存储过程的元数据时行为不同。

众所周知,当在其中使用临时表时,sys.sp_describe_first_result_set无法检索存储过程的元数据。

为简单起见,这是一个简单的例子。

CREATE PROCEDURE dbo.Test
    @Seed INT = 0
AS
BEGIN
    CREATE TABLE #MyTemp (
        ID INT NOT NULL
    );

    INSERT INTO #MyTemp (ID)
    VALUES
          (@Seed + 1)
        , (@Seed + 2)
        , (@Seed + 3)
    ;

    SELECT
        ID
    FROM
        #MyTemp
END

执行此SP将返回一个结果集,其中我们有一列(ID)和三个记录。

EXEC dbo.Test
    @Seed = 1;

结果是:

ID
-----------
2
3
4

但是,尝试获取元数据将失败:

EXEC sys.sp_describe_first_result_set @tsql = N'EXEC dbo.Test @Seed = 1;';

结果是:

Msg 11526, Level 16, State 1, Procedure sp_describe_first_result_set, Line 1 [Batch Start Line 24]
The metadata could not be determined because statement 'INSERT INTO #MyTemp (ID)
    VALUES
          (@Seed + 1)
        , (@Seed + 2)
        , (@Seed + 3)' in procedure 'Test' uses a temp table.

(这是预期的,因为这是sp_describe_first_result_set的已知限制)

问题是,当我们的第三方应用程序遇到此错误时,它会执行SP两次(首先分析结果集并创建临时表,然后执行INSERT .. EXEC将数据加载到它创建的临时表中)。

当元数据可用时,它将使用sys.sp_describe_first_result_set获取元数据并使用该信息创建临时表。

由于我们在2012版本之下没有任何SQL Server,我可以使用WITH RESULT SETS子句,但是在该应用程序中无法配置它,或者手动提供元数据信息。

如何使用此SP为应用程序提供元数据?

我在答案中提供了两个解决方案,但我很好奇是否有一个我不知道的问题。

答案

我目前的解决方案是创建一个包装器存储过程,它执行现有的过程,传递所有参数,但定义结果集的元数据。

要继续问题中的示例:

EXEC sp_rename 'dbo.Test', 'Test_Logic', 'OBJECT';
GO

CREATE PROCEDURE dbo.Test
    @Seed INT = 0
AS
BEGIN
    EXEC dbo.Test_Logic
        @Seed = @Seed
    WITH RESULT SETS (
        (
            ID INT
        )
    )
    ;
END

现在,如果我尝试获取元数据,我可以得到它:

EXEC sys.sp_describe_first_result_set @tsql = N'EXEC dbo.Test @Seed = 1;';

结果是:

is_hidden column_ordinal name                                                                                                                             is_nullable system_type_id system_type_name                                                                                                                 max_length precision scale collation_name                                                                                                                   user_type_id user_type_database                                                                                                               user_type_schema                                                                                                                 user_type_name                                                                                                                   assembly_qualified_type_name                                                                                                                                                                                                                                     xml_collection_id xml_collection_database                                                                                                          xml_collection_schema                                                                                                            xml_collection_name                                                                                                              is_xml_document is_case_sensitive is_fixed_length_clr_type source_server                                                                                                                    source_database                                                                                                                  source_schema                                                                                                                    source_table                                                                                                                     source_column                                                                                                                    is_identity_column is_part_of_unique_key is_updateable is_computed_column is_sparse_column_set ordinal_in_order_by_list order_by_is_descending order_by_list_length tds_type_id tds_length  tds_collation_id tds_collation_sort_id
--------- -------------- -------------------------------------------------------------------------------------------------------------------------------- ----------- -------------- -------------------------------------------------------------------------------------------------------------------------------- ---------- --------- ----- -------------------------------------------------------------------------------------------------------------------------------- ------------ -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- --------------- ----------------- ------------------------ -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ------------------ --------------------- ------------- ------------------ -------------------- ------------------------ ---------------------- -------------------- ----------- ----------- ---------------- ---------------------
0         1              ID                                                                                                                               1           56             int                                                                                                                              4          10        0     NULL                                                                                                                             NULL         NULL                                                                                                                             NULL                                                                                                                             NULL                                                                                                                             NULL                                                                                                                                                                                                                                                             NULL              NULL                                                                                                                             NULL                                                                                                                             NULL                                                                                                                             0               0                 0                        NULL                                                                                                                             NULL                                                                                                                             NULL                                                                                                                             NULL                                                                                                                             NULL                                                                                                                             NULL               NULL                  NULL          NULL               NULL                 NULL                     NULL                   NULL                 38          4           NULL             NULL

(这看起来很糟糕,但它有效)

缺点是现在我必须维护两个SP,然后有一个SP执行。

替代方案

另一种解决方案是使用动态sql和sys.sp_executesql使用WITH RES

以上是关于使用临时表时,描述第一个结果集的SQL Server失败(sp_describe_first_result_set)的主要内容,如果未能解决你的问题,请参考以下文章

如何将单个结果集从返回多个集的 SQL 存储过程保存到临时表?

使用临时表时 SQL Server 显示“无效的对象名称 '#temp'”

查看或临时表 - 在 MS SQL Server 中使用哪个?

如何捕捉SQLSERVER到VFP临时表时的进度

T-SQL 公用表表达式(CTE)

连接表时的 SQL 聚合