Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
896 views
in Technique[技术] by (71.8m points)

sql server - INSERT INTO with exec with multiple result sets

SQL Server allows me to insert the returned result set of a stored procedure as:

DECLARE @T TABLE (
  ID int,
  Name varchar(255),
  Amount money)

INSERT INTO @T
exec dbo.pVendorBalance 

This works as long as the stored procedure only returns 1 result set.

Is there a way to make this work if the stored procedure returns several result sets?

E.g.

DECLARE @T1 (...)
DECLARE @T2 (...)

INSERT INTO @T1 THEN INTO @T2
exec dbo.pVendorBalance 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One workaround to this problem is using OUTPUT parameters (JSON/XML) instead of resultsets.

CREATE TABLE tab1(ID INT, Name NVARCHAR(10), Amount MONEY);
INSERT INTO tab1(ID, Name, Amount)
VALUES (1, 'Alexander', 10),(2, 'Jimmy', 100), (6, 'Billy', 20);

CREATE PROCEDURE dbo.pVendorBalance 
AS
BEGIN
   -- first resultset
   SELECT * FROM tab1 WHERE ID <=2;

   -- second resultset
   SELECT * FROM tab1 WHERE ID > 5;
END;

Version with OUT params:

CREATE PROCEDURE dbo.pVendorBalance2 
         @resultSet1 NVARCHAR(MAX) OUT,
         @resultSet2 NVARCHAR(MAX) OUT
AS
BEGIN
    SELECT @resultSet1 = (SELECT * FROM tab1 WHERE ID <=2 FOR JSON AUTO),
           @resultSet2 = (SELECT * FROM tab1 WHERE ID > 5 FOR JSON AUTO);
END;

And final call:

DECLARE @r1 NVARCHAR(MAX), @r2 NVARCHAR(MAX);
EXEC dbo.pVendorBalance2 @r1 OUT, @r2 OUT;


-- first resultset as table
SELECT * 
INTO #t1
FROM OpenJson(@r1)
WITH (ID int '$.ID', [Name] NVARCHAR(50) '$.Name',Amount money '$.Amount');

-- second resultset as table
SELECT *  
INTO #t2
FROM OpenJson(@r2)
WITH (ID int '$.ID', [Name] NVARCHAR(50) '$.Name',Amount money '$.Amount');

SELECT * FROM #t1;
SELECT * FROM #t2;

DBFiddle Demo

EDIT:

Second approach is to use tSQLt.ResultSetFilter CLR function (part of tSQLt testing framework):

The ResultSetFilter procedure provides the ability to retrieve a single result set from a statement which produces multiple result sets.

CREATE TABLE #DatabaseSize (
    database_name nvarchar(128),
    database_size varchar(18),
    unallocated_space varchar(18)
);

CREATE TABLE #ReservedSpaceUsed (
    reserved VARCHAR(18),
    data VARCHAR(18),
    index_size VARCHAR(18),
    unused VARCHAR(18)
);

INSERT INTO #DatabaseSize
EXEC tSQLt.ResultSetFilter 1, 'EXEC sp_spaceused';

INSERT INTO #ReservedSpaceUsed
EXEC tSQLt.ResultSetFilter 2, 'EXEC sp_spaceused';

SELECT * FROM #DatabaseSize;
SELECT * FROM #ReservedSpaceUsed;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...