SQL Server 2014:如何单次执行存储过程并将两个结果集插入临时表
嘿,这个需求完全可行!不过具体实现得看你的存储过程有没有副作用,我给你分两种场景整理了方案:
场景1:存储过程无副作用(仅返回查询结果)
如果你的存储过程只是做查询,不会修改数据、生成唯一编号或者产生其他不可逆的操作,那最简单的方法就是分两次执行存储过程,分别把结果插入对应的临时表:
-- 先创建两个临时表,结构和存储过程返回的结果集匹配 CREATE TABLE #tmp1 (Country VARCHAR(MAX), City VARCHAR(MAX), Qty INT) CREATE TABLE #tmp2 (Id INT, Color VARCHAR(MAX)) -- 插入第一个结果集 INSERT INTO #tmp1 EXEC Test -- 插入第二个结果集 INSERT INTO #tmp2 EXEC Test
这种方案代码简洁,容易维护,适合大多数普通查询类的存储过程。
场景2:必须单次执行存储过程(有副作用)
如果你的存储过程会修改数据、生成日志或者有其他副作用,执行两次会导致数据异常,那纯T-SQL本身没法直接搞定,但可以通过这些方式实现:
推荐:用客户端代码处理
比如用C#、PowerShell这类客户端语言来执行存储过程,然后遍历返回的多个结果集,分别插入临时表。拿C#举个例子:
using (var conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); var cmd = new SqlCommand("Test", conn) { CommandType = CommandType.StoredProcedure }; var reader = cmd.ExecuteReader(); // 处理第一个结果集,插入#tmp1 using (var bulkCopy = new SqlBulkCopy(conn)) { bulkCopy.DestinationTableName = "#tmp1"; bulkCopy.WriteToServer(reader); } // 切换到第二个结果集 reader.NextResult(); // 处理第二个结果集,插入#tmp2 using (var bulkCopy = new SqlBulkCopy(conn)) { bulkCopy.DestinationTableName = "#tmp2"; bulkCopy.WriteToServer(reader); } }
这种方法能确保存储过程只执行一次,同时完整捕获所有结果集,是最可靠的方案。
备选:CLR存储过程
你可以写一个.NET的CLR存储过程,在代码里捕获原存储过程的多个结果集,再把数据插入到目标表。不过这种方法需要开启SQL Server的CLR集成,还有一定的开发成本,除非你本身熟悉CLR开发,否则不优先推荐。
不推荐:复杂T-SQL技巧
也可以用OPENROWSET把存储过程的结果转成XML,再拆分XML提取多个结果集,但这种方法对结果集结构要求高,代码繁琐,容易出问题,一般不建议用。
总结
如果没副作用,直接用场景1的方法就行;要是必须单次执行,优先用客户端代码的方案,省心又靠谱。
内容的提问来源于stack exchange,提问作者Przemek
相关产品推荐
相关产品推荐

