从返回多个结果集的存储过程中插入临时表

Posted

技术标签:

【中文标题】从返回多个结果集的存储过程中插入临时表【英文标题】:Insert Into temp table from a stored procedure that returns multiple result sets 【发布时间】:2011-09-17 07:48:22 【问题描述】:

考虑下面的sql

一个名为 myProc 的存储过程,它返回两个结果集。结果集 1 返回 column1、column2。结果集 2 返回第 3 列、第 4 列、第 5 列。

以下 sql 将失败,因为临时表仅定义了 2 个 int 列。

Create Table #temp1(
Column1 int,
Column2 int)

insert into #temp1 exec myProc

我的问题是是否可以将第一个结果集插入#temp1?

【问题讨论】:

***.com/questions/209383/… How to SELECT * INTO [temp table] FROM [Stored Procedure]的可能重复 【参考方案1】:

旧帖子,但我遇到了同样的问题,虽然上面提到的答案有点相关,但 OP 的问题是关于返回多个集合的 SP。除了重写 SP 以将其拆分为更小的 SP 之外,我能找到的唯一解决方案是编写一个 SQL CLR 过程来执行 SP 并仅返回所需的结果集。该过程获取所需结果集的索引,执行SqlCommand 以运行初始T-SQL SP,然后循环通过SqlDataReader 结果,直到找到所需的结果集并返回相应的记录。以下代码是SQL CLR 过程的一部分:

SqlDataReader rdr = command.ExecuteReader();
int index = 0;
bool bContinue = true;
while (index < resultSetIndex.Value)

    if (!rdr.NextResult())
    
        bContinue = false;
        break;
    
    index++;

if (!bContinue)
    throw new Exception("Unable to read result sets.");

.......

List<SqlMetaData> metadataList = new List<SqlMetaData>();
for (int i = 0; i < rdr.FieldCount; i++)

    string dbTypeName = rdr.GetDataTypeName(i);
    SqlMetaData metadata;
    if (dbTypeName.ToLower().Contains("char"))
        metadata = new SqlMetaData(rdr.GetName(i), (SqlDbType)Enum.Parse(typeof(SqlDbType), dbTypeName, true), 50);
    else
        metadata = new SqlMetaData(rdr.GetName(i), (SqlDbType)Enum.Parse(typeof(SqlDbType), dbTypeName, true));
    metadataList.Add(metadata);

SqlDataRecord record = new SqlDataRecord(metadataList.ToArray());
object[] values = new object[rdr.FieldCount];
if (rdr.HasRows)

    SqlContext.Pipe.SendResultsStart(record);
    while (rdr.Read())
    
        rdr.GetValues(values);
        record.SetValues(values);
        SqlContext.Pipe.SendResultsRow(record);
    
    SqlContext.Pipe.SendResultsEnd();

【讨论】:

+1 除了从SqlDataReader 提取元数据和为SqlDataRecord 创建SqlMetaData 的过度简化之外,这可能会导致问题取决于返回的数据类型,这几乎是从存储过程中获取特定结果集的唯一方法。【参考方案2】:

还有一种方法

SELECT * into #temp 
  from OPENROWSET('SQLNCLI', 'Server=(local)\\(instance);Trusted_Connection=yes;',
'EXEC (database).(schema).(sproc)')

这会将第一个结果集插入#temp

【讨论】:

以上是关于从返回多个结果集的存储过程中插入临时表的主要内容,如果未能解决你的问题,请参考以下文章

如何在存储过程中直接使用另一个存储过程返回的数据集

将存储过程结果插入临时表

如何从存储过程返回的游标将数据插入临时表

SQL存储过程多个结果到临时表中

oracle存储过程中临时表的使用,该怎么处理

mssql 里面存储过程插入了条数据之后的返回