使用临时表时,描述第一个结果集的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和 以上是关于使用临时表时,描述第一个结果集的SQL Server失败(sp_describe_first_result_set)的主要内容,如果未能解决你的问题,请参考以下文章 如何将单个结果集从返回多个集的 SQL 存储过程保存到临时表? 使用临时表时 SQL Server 显示“无效的对象名称 '#temp'”sys.sp_executesql
使用WITH RES