动态查询“ INSERT EXEC语句不能嵌套”

时间:2019-09-20 14:25:25

标签: sql-server tsql stored-procedures dynamic-sql

背景

我有一个过程,该过程具有来自动态SQL的INSERT INTO ... EXEC (@sql)。 该过程的结果在过程之外的INSERTed INTO表中。当我尝试这样做时,我得到一个错误:

  

[S0001] [8164]不能嵌套INSERT EXEC语句。

在其他问题中讨论了此错误,但针对内部过程的调用而不是动态SQL:

错误示例:

-- =================================
-- table with test data
-- =================================

CREATE TABLE dbo.TestInsertIntoDynamicData1
(
  data nvarchar(max)
)

INSERT INTO dbo.TestInsertIntoDynamicData1
VALUES ('one1'), ('two1'), ('three1')

GO

-- =================================
-- another table with test data
-- =================================

CREATE TABLE dbo.TestInsertIntoDynamicData2
(
  data nvarchar(max)
)

INSERT INTO dbo.TestInsertIntoDynamicData2
VALUES ('one2'), ('two2'), ('three2')

GO

-- =================================
-- procedure with dynamic query
-- =================================

CREATE PROCEDURE dbo.TestInsertIntoDynamicProc
    @TableName nvarchar(100)
AS
  BEGIN
    DECLARE @Results table(
      data nvarchar(max)
    )

    DECLARE @sql nvarchar(max)
    SET @sql = '
      SELECT data
      FROM dbo.' + @TableName + ';
    '

    -- FIRST INSERT INTO ... EXEC ...
    INSERT INTO @Results  -- this INSERT is required for example
    EXEC (@sql)

    SELECT *
    FROM @Results;
  END
GO

-- =================================
-- CALL
-- =================================

DECLARE @ResultsOfProc table(
  data nvarchar(max)
)

-- SECOND INSERT INTO ... EXEC ...
INSERT INTO @ResultsOfProc (data)
EXEC dbo.TestInsertIntoDynamicProc @TableName = 'TestInsertIntoDynamicData2'

SELECT *
FROM @ResultsOfProc;

GO

DROP TABLE dbo.TestInsertIntoDynamicData1
DROP TABLE dbo.TestInsertIntoDynamicData2
DROP PROCEDURE dbo.TestInsertIntoDynamicProc

https://stackoverflow.com/a/2917775/7573844

问题

我们如何解决这个错误?

1 个答案:

答案 0 :(得分:0)

INSERT INTO移至动态查询。 将表变量重构为临时表,以便在动态查询中使用它。 固定步骤:

CREATE PROCEDURE dbo.TestInsertIntoDynamicProcFixed
    @TableName nvarchar(100)
AS
  BEGIN
    CREATE TABLE #Results (  -- refactor to temp table
      data nvarchar(max)
    )

    DECLARE @sql nvarchar(max)
    SET @sql = '
      INSERT INTO #Results         -- move INSERT to here
      SELECT data
      FROM dbo.' + @TableName + ';
    '

    -- FIRST INSERT INTO ... EXEC ...
    EXEC (@sql)

    SELECT *
    FROM #Results;
  END
GO