【问题标题】:An INSERT EXEC statement cannot be nested. Dealing with errorINSERT EXEC 语句不能嵌套。处理错误
【发布时间】:2017-10-18 11:25:51
【问题描述】:

不重复。这里的问题是它有不同的结构。我对我能改变什么和不能改变什么有一些限制。这里我有确切的例子,其他票没有。 OPENROWSET 也不能应用,因为 test1 循环遍历所有数据库(using EXEC sp_MSforeachdb @sql)。我不能使用它,因为在 OPENROWSET 中你必须指定你从哪个数据库运行程序

假设我有这两个 SP:

create procedure test1
@ProcName  varchar(155)
as
begin

if OBJECT_ID('tempdb..#testt') is not null drop table #testt
create table #testt1(a int, b int)

insert #testt1
exec @ProcName

select * from #testt1
end

create procedure test2  
as
begin

declare @sql varchar(155)

if OBJECT_ID('tempdb..#testt2') is not null drop table #testt2
create table #testt2(a int, b int)

select @sql = 'select 1 as a,2 as b'

insert #testt2
exec (@sql)

select * from #testt2

end

当我运行exec test1 @ProcName = 'Test2' 时,它返回错误:

INSERT EXEC 语句不能嵌套。

这里的问题是我不能停止在test2 中使用insert exec。并且 test1 应该将 @ProcName 作为变量

解决这个问题最轻松的方法是什么?

【问题讨论】:

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

insert 语句放入 test2 程序解决了问题

【讨论】:

    【解决方案2】:

    尝试用表变量替换第二个过程中的临时表,然后使用 OPENQUERY(如 http://www.sommarskog.se/share_data.html 中所述),如下所示:

    CREATE DATABASE Database1
    CREATE DATABASE Database2
    GO
    DECLARE @ProcedureTest2 NVARCHAR(MAX)
    SET @ProcedureTest2='create procedure test2  
    as
    begin
    SET NOCOUNT ON 
    
    declare @sql varchar(155)
    
    DECLARE @testt2 TABLE (a int, b int)
    
    select @sql = ''select 1 as a,2 as b''
    
    insert @testt2
    exec (@sql)
    
    select * from @testt2
    
    end'
    
    DECLARE @SQL NVARCHAR(MAX)
    SET @SQL='USE Database1 EXEC('''+REPLACE(@ProcedureTest2,'''','''''')+''')'
    EXEC(@SQL)
    SET @SQL='USE Database2 EXEC('''+REPLACE(@ProcedureTest2,'''','''''')+''')'
    EXEC(@SQL)
    
    GO
    EXEC sp_addlinkedserver @server = 'LOCALSERVER',  @srvproduct = '', @provider = 'SQLOLEDB', @datasrc = @@servername
    
    GO
    CREATE procedure test1
    @ProcName  varchar(155)
    as
    begin
    
    if OBJECT_ID('tempdb..#testt1') is not null drop table #testt1
    create table #testt1(a int, b int)
    
    DECLARE @Databases TABLE (DBName sysname PRIMARY KEY)
    INSERT INTO @Databases VALUES ('Database1')
    INSERT INTO @Databases VALUES ('Database2')
    
    DECLARE Databases CURSOR LOCAL READ_ONLY FOR
    SELECT * FROM @Databases d
    
    DECLARE @DBName sysname
    OPEN Databases
    
    WHILE 1=1 BEGIN
        FETCH NEXT FROM Databases INTO @DBName
        IF @@FETCH_STATUS<>0 BREAK
    
        DECLARE @SQL1 NVARCHAR(500), @SQL2 NVARCHAR(1000)
        SET @SQL1='EXEC '+QUOTENAME(@DBName)+'.dbo.'+QUOTENAME(@ProcName)
        SET @SQL2='SELECT * FROM OPENQUERY(LOCALSERVER, '+QUOTENAME(@SQL1,'''')+')'
    
        PRINT @SQL2
        INSERT INTO #testt1
        EXEC (@SQL2)
    END
    
    CLOSE Databases
    DEALLOCATE Databases
    
    select * from #testt1
    end
    
    GO
    --EXEC [Database1].dbo.[test2]
    
    --SELECT * FROM OPENQUERY(LOCALSERVER, 'EXEC [Database1].dbo.[test2]')
    
    EXEC dbo.test1 'test2'
    
    GO
    EXEC sp_dropserver 'LOCALSERVER'
    DROP PROCEDURE test1
    DROP DATABASE Database1
    DROP DATABASE Database2
    

    【讨论】:

      猜你喜欢
      • 2014-07-07
      • 2013-05-17
      • 2016-05-02
      • 2019-11-12
      • 1970-01-01
      • 2020-01-21
      • 2018-03-20
      • 2012-04-24
      相关资源
      最近更新 更多