Sql-Server

在這種情況下如何避免“無法嵌套 INSERT EXEC 語句”異常?

  • May 13, 2020

當我執行以下腳本時,它執行良好:

declare @temp table
(
   name varchar(255),
   field varchar(255),
   filename varchar(255),
   filegroup varchar(255),
   size varchar(255),
   maxsize varchar(255),
   growth varchar(255),
   usage varchar(255)
);
INSERT @temp
  exec sp_msforeachdb  @command1='use ?; Exec sp_helpfile;' 

但是當我使用自己的 sp_foreachdb 過程時,原始碼在下面的這個連結上:

更可靠、更靈活的 sp_MSforeachdb

declare @temp table
(
   name varchar(255),
   field varchar(255),
   filename varchar(255),
   filegroup varchar(255),
   size varchar(255),
   maxsize varchar(255),
   growth varchar(255),
   usage varchar(255)
);
INSERT @temp
  exec sp_foreachdb  @command='use ?; Exec sp_helpfile;'   

我得到一個異常(請注意我在該過程中添加了異常處理)

--EXCEPTION WAS CAUGHT--
THE ERROR NUMBER:8164

SEVERITY: 16
STATE: 1

PROCEDURE: sp_foreachdb
LINE NUMBER: 165

ERROR MESSAGE: 
An INSERT EXEC statement cannot be nested.
------------------------------------ the sql ------------------------------------

SELECT name FROM sys.databases WHERE 1=1 AND state_desc = N'ONLINE' AND is_read_only = 0
Msg 16916, Level 16, State 1, Procedure sp_foreachdb, Line 239
A cursor with the name 'c' does not exist.
Msg 16916, Level 16, State 1, Procedure sp_foreachdb, Line 240
A cursor with the name 'c' does not exist.

(0 row(s) affected)

Aaron’s 的原始碼sp_foreachdb包含以下行:

INSERT #x EXEC sp_executesql @sql;

根據你的錯誤資訊:

INSERT EXEC 語句不能嵌套。

因此,下面的程式碼將無效,因為它是嵌套INSERT xxx EXEC xxx程式碼。

INSERT @temp
exec sp_msforeachdb  @command1='use ?; Exec sp_helpfile;'

如果 sp_foreachdb 將返回單個結果集,那麼通過分佈式查詢方法連接到您自己的伺服器就可以了。

create table #temp 
(
   name varchar(255),
   field varchar(255),
   filename varchar(255),
   filegroup varchar(255),
   size varchar(255),
   maxsize varchar(255),
   growth varchar(255),
   usage varchar(255)
);

insert into #temp
select  *
FROM OPENROWSET('SQLNCLI', 'SERVER=****;UID=****;PWD=****',
' exec sp_foreachdb  @command=''  Exec ?..sp_helpfile;''  WITH RESULT SETS         ((name varchar(255),
field varchar(255),
filename varchar(255),
filegroup varchar(255),
size varchar(255),
maxsize varchar(255),
growth varchar(255),
usage varchar(255))); ')

select * from #temp

上面的查詢將只返回 sp_foreachdb 執行的第一個結果集。但下面的查詢將在單個結果集中返回所有數據庫的結果。

create table #temp 
(
   name varchar(255),
   field varchar(255),
   filename varchar(255),
   filegroup varchar(255),
   size varchar(255),
   maxsize varchar(255),
   growth varchar(255),
   usage varchar(255)
);

exec sp_foreachdb  @command='INSERT INTO #temp  Exec ?..sp_helpfile;'
select * from #temp

引用自:https://dba.stackexchange.com/questions/160739