Sql-Server

將 sp_executesql 的參數傳遞給 sp_ineachdb 或 sp_foreachdb

  • April 24, 2019

我經常需要在不同數據庫的上下文中執行sp_executesql

我想將與sp_executesql相同的參數添加到sp_ineachdb

但是當我看到這個時: – SQL Server、Azure SQL 數據庫、Azure SQL 數據倉庫、並行數據倉庫的語法

sp_executesql

$$ @stmt = $$陳述 $$ { , [ @params = ] N’@parameter_name data_type [ OUT | OUTPUT ][ ,…n ]’ } { , [ @param1 = ] ‘value1’ [ ,…n ] } $$

我不知道如何定義所有要添加到sp_ineachdb.

例如,下面的程式碼檢查數據庫中的索引:

   declare @IndexName NVARCHAR(128)='si_xdes_id'
   declare @dbname NVARCHAR(128) = db_name()
   DECLARE @sql NVARCHAR(MAX)
   DECLARE @ParamDefinition NVARCHAR(MAX)
   DECLARE @retval INT  

IF @IndexName IS NOT NULL /*validate the index exists in the @dbname database*/
  BEGIN

       SELECT @sql = 'SELECT @retvalOUT = CASE WHEN EXISTS (
                              SELECT * FROM ' + @dbname + '.sys.indexes I WHERE I.Name = @IndexName  ) 
                              THEN 1 ELSE 0 END '

       SET @ParamDefinition = N'@retvalOUT int OUTPUT,
                               @IndexName SYSNAME';

       EXEC sp_executesql @SQL, @ParamDefinition, @retvalOUT= @retval OUTPUT, @IndexName  = @IndexName;

       IF (@retval = 0) 
           BEGIN

              --RAISERROR('The index called %s does not exist on database %s',16,1,@IndexName,@dbname)
              RETURN

           END 
  END

為了讓我將它與sp_ineachdb結合使用,我必須將整個內容包裝到動態 sql 中:

   DECLARE @sql NVARCHAR(MAX)=

'   declare @IndexName NVARCHAR(128)=''uc_emailAddress''
   declare @dbname NVARCHAR(128) = db_name()
   DECLARE @sql NVARCHAR(MAX)
   DECLARE @ParamDefinition NVARCHAR(MAX)
   DECLARE @retval INT  

IF @IndexName IS NOT NULL /*validate the index exists in the @dbname database*/
  BEGIN

       SELECT @sql = ''SELECT @retvalOUT = CASE WHEN EXISTS (
                              SELECT * FROM '' + @dbname + ''.sys.indexes I WHERE I.Name = @IndexName  ) 
                              THEN 1 ELSE 0 END ''

       SET @ParamDefinition = N''@retvalOUT int OUTPUT,
                               @IndexName SYSNAME'';

       EXEC sp_executesql @SQL, @ParamDefinition, @retvalOUT= @retval OUTPUT, @IndexName  = @IndexName;

       select @dbname,@retval

       IF (@retval = 0) 
           BEGIN

              --RAISERROR(''The index called %s does not exist on database %s'',16,1,@IndexName,@dbname)
              RETURN

           END 
  END
'

if object_id('tempdb..#radhe') is not null
  drop table #radhe
create table #radhe(dbname sysname, the_index_exist_here int)
insert into #radhe
EXEC sp_ineachdb @command = @sql, @user_only = 1;

select * from #radhe

這給了我:

在此處輸入圖像描述

問題:

有沒有更簡單的方法來完成這項工作?

我想將 目前傳遞給sp_executesql的所有參數傳遞給sp_ineachdb ,並優雅地收集輸出。

這有可能嗎?

不幸的是,sp_ineachdb設計時並沒有考慮到這個特定的案例(帶參數的嵌套動態 SQL),而且我不知道你是否可以在沒有任何動態 SQL 的情況下使用這個腳本做所有你想做的事情。我認為這種方法會更簡單一些——你必須呼叫sp_ineachdb兩次,但動態 SQL 部分要簡單得多,而且你不必為過程傳遞參數以依次傳遞給它自己的內部sp_executesql稱呼。

DECLARE @indexname nvarchar(128) = N'uc_emailAddress',
       @cmd       nvarchar(max) = N'SELECT db = DB_NAME(),0;';

DROP TABLE IF EXISTS #radhe;    

CREATE TABLE #radhe
(
 dbname sysname, 
 indexname nvarchar(128), 
 the_index_exist_here bit
);

INSERT #radhe(dbname,the_index_exist_here)
EXEC master.dbo.sp_ineachdb @command = @cmd, @user_only = 1;

UPDATE #radhe SET indexname = @indexname;

SET @cmd = N'UPDATE r SET the_index_exist_here = 1
   FROM #radhe AS r
   INNER JOIN sys.indexes AS i
   ON r.dbname = DB_NAME()
   AND i.name = r.indexname;';

EXEC master.dbo.sp_ineachdb @cmd;

SELECT dbname, the_index_exist_here FROM #radhe;

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