我从客户咨询团队的微软高级项目经理史蒂夫霍华德那里找到了一个权威的答案:
AS FOR XML 不会将来自已执行语句或存储过程的非 XML 表格结果转换为 XML。AS FOR XML 指定EXECUTE 语句调用的语句或存储过程的 XML 结果将被转换为好像它们是由 SELECT ... FOR XML ... 语句生成的格式。原始语句中类型指令的所有格式都将被删除,返回的结果就像没有指定类型指令一样。
但他也为我提供了这个替代方案:
/*
Demo of how to display results from a stored procedure in XML
Author: Steve Howard
Date: June 21, 2012
Intended as a demo only. Adapt to your purposes
*/
-- for this demo, declare a variable @tsql_batch to hold the batch to be executed
-- note that this could become a parameter in a stored procedure if this is how this is used
declare @tsql_batch nvarchar(4000)
-- set the variable for the demo only
-- you will need to set this in your testing
set @tsql_batch = N'exec forDemo'
-- declare a table to hold the results of sp_describe_first_result_set
-- note that this can also be used for multiple result sets. See the documentation
-- at: http://technet.microsoft.com/en-us/library/ff878602(v=sql.110).aspx
declare @resultDescription table
(
is_hidden bit null
, column_ordinal int not null primary key
, name sysname not null
, is_nullable bit null
, system_type_id int null
, system_type_name nvarchar(256) null
, max_length smallint null
, precision tinyint null
, scale tinyint null
, collation_name sysname null
, user_type_id int null
, user_type_database sysname null
, user_type_schema sysname null
, user_type_name sysname null
, assembly_qualified_type_name nvarchar(4000) null
, xml_collection_id int null
, xml_collection_database sysname null
, xml_collection_schema sysname null
, xml_collection_name sysname null
, is_xml_document bit null
, is_case_sensitive bit null
, is_fixed_length_clr_type bit null
, source_server sysname null
, source_database sysname null
, source_schema sysname null
, source_table sysname null
, source_column sysname null
, is_identity_column bit null
, is_part_of_unique_key bit null
, is_updateable bit null
, is_computed_column bit null
, is_sparse_column_set bit null
, ordinal_in_order_by_list smallint null
, order_by_list_length smallint null
, order_by_is_descending smallint null
, tds_type_id int null
, tds_length int null
, tcs_collation_id int null
, tds_collation_sort_id tinyint null
)
-- populate the table variable
insert into @resultDescription
exec sp_describe_first_result_set @tsql_batch
-- declare the cursor to create the "create table statement:
declare crs cursor for SELECT '[' + name + '] ' + system_type_name + ' ' + case is_nullable when 0 then 'not null ' else 'null ' end + '
' FROM @resultDescription order by column_ordinal asc
-- variables to hold the statement to be executes as well as the current value from the cursor
declare @exec NVARCHAR(4000)
declare @curVal nvarchar(1000)
open crs
fetch next from crs into @curval
-- begin building the dynamic SQL statement to be executed
set @exec = 'DECLARE @temp TABLE
(
' + @curval
fetch next from crs into @curval
while @@FETCH_STATUS = 0
begin
set @exec = @exec + ', ' + @curVal
fetch next from crs into @curVal
end
close crs
deallocate crs
set @exec = @exec + '
)
INSERT INTO @temp
exec sp_executesql N''' + @tsql_batch + '''
SELECT * FROM @temp FOR XML AUTO
'
-- get the results
exec (@exec)
-- of you want to just see the statement that was executed:
print @exec