web-dev-qa-db-ja.com

すべてのデータベースでselectステートメントを実行する必要がある

複数のデータベースにわたって以下のようなクエリを実行しようとしています

select ParamValue from Table1 where paramname = 'SYSTEM_LICENSE'

各DBには以下のような名前が付けられており、一部のDBは除外する必要があります。

「Customer_123」

Sp_MSforeachdbの使用を検討しましたが、サポートされておらず、うまく機能していませんでした。カーソルの書き方を考えてみましたが、うまくいきませんでした。この時点で、私が探していることを実際に書ける人から助けを求めています。

2
Thorin

これは、私が使用する「各dbで何かを実行する」テンプレートで、例に少し合わせてあります。

--Create a table to hold the query results
CREATE TABLE #licenselist
    (dbid smallint, dbname sysname, system_license varchar(99));

DECLARE @fixedname nvarchar(150);

--Include or exclude whatever databases you want
DECLARE dbCursor CURSOR FOR
    SELECT REPLACE(QUOTENAME(name),'''','''''') --For db names with annoying characters
    FROM master.sys.databases
    WHERE state_desc = 'ONLINE'
    AND HAS_DBACCESS(name) = 1                  --Added at @SolomonRutzky's suggestion
    AND name NOT IN ('master','msdb','model','tempdb');

OPEN dbCursor;
FETCH NEXT FROM dbCursor INTO @fixedname;

WHILE @@FETCH_STATUS = 0   
BEGIN   
       EXEC ('USE ' + @fixedname + ';' + 
        'INSERT INTO #licenselist
         SELECT DB_ID() as dbid, DB_NAME() as dbname, ParamValue as system_license
         FROM Table1 
         WHERE paramname = ''SYSTEM_LICENSE'';');

       FETCH NEXT FROM dbCursor INTO @fixedname;
END;   

CLOSE dbCursor;
DEALLOCATE dbCursor;

SELECT * FROM #licenselist 

DROP TABLE #licenselist

[〜#〜] edit [〜#〜]:少し合理化され、生の@dbname変数が削除され、代わりに元のクエリで修正されました。

5
BradC

改めて感謝します。少し変更して、必要なDBのみをクエリし、YESの結果のみを出力しました。

--Create a table to hold the query results
CREATE TABLE #licenselist
    (dbname sysname, system_license varchar(99));

DECLARE @dbname SYSNAME;
DECLARE @fixedname nvarchar(150);

--Include or exclude whatever databases you want
DECLARE dbCursor CURSOR FOR
    SELECT name FROM master.sys.databases
    WHERE DATABASEPROPERTYEX(name, 'Status') = 'ONLINE'
    AND name like 'SOMETHING_%'
    AND name not like '%_SOMETHINGELSE'
    --AND name NOT IN ('master','msdb','model','tempdb');

OPEN dbCursor;
FETCH NEXT FROM dbCursor INTO @dbname;

WHILE @@FETCH_STATUS = 0   
BEGIN   
       --Fix for invalid characters in DB names
       SELECT @fixedname = REPLACE(QUOTENAME(@dbname),'''','''''');     
       EXEC ('USE ' + @fixedname + ';' + 
        'INSERT INTO #licenselist
         SELECT DB_NAME() as dbname, ParamValue as system_license
         FROM TABLE1 
         WHERE paramname = ''STRING_VALUE'';');

       FETCH NEXT FROM dbCursor INTO @dbname;
END;   

CLOSE dbCursor;
DEALLOCATE dbCursor;

SELECT *
FROM #licenselist
where system_license='YES'
ORDER by dbname desc

DROP TABLE #licenselist
0
Thorin