TSQLを使用してデータベースを動的に変更する方法


11

SSMSのコンテキストを動的SQLで指定されたデータベースに動的に変更しようとすると問題が発生します。

EXEC sys.sp_executesql N'USE db1 ' ;

正常に実行されますが、SSMSのデータベースコンテキストは変更されません。

上記のように少し変更してみました

DECLARE @sql NVARCHAR(100) DECLARE @db NVARCHAR(50)
SET @db = N'db1' SET @sql = N'Use ' + @db
EXEC sp_executesql @sql

繰り返しになりますが、正常に実行されますが、データベースは変更されません。


4
SSMSで使用しているセッションのsp_executesql内のコンテキストを変更することはできません。コンテキストは動的SQLセッション中にのみ有効です-SSMSセッションでは有効ではありません。
Lothar Kraner 2017

回答:


7

SSMS WILL NOT、IのREPEAT、WILL NOTの A使用するコマンドYOU RUNでの動的SQLの内容に切り替えます。

選択したデータベース内で他の動的SQLを実行することが最終的な目標である場合、これは十分簡単です。

DECLARE @db sysname = N'db1';

DECLARE @exec nvarchar(max) = QUOTENAME(@db) + N'.sys.sp_executesql',
        @sql  nvarchar(max) = N'SELECT DB_NAME();';

EXEC @exec @sql;

パラメータを渡す必要がある場合、問題ありません:

DECLARE @db sysname = N'db1', @i int = 1;

DECLARE @exec nvarchar(max) = QUOTENAME(@db) + N'.sys.sp_executesql',
        @sql  nvarchar(max) = N'SELECT DB_NAME(), @i;';

EXEC @exec @sql, N'@i int', @i;

選択したデータベース内で静的 SQL を実行することが目的である場合は、その静的SQLを各データベースのストアドプロシージャに格納し、次のように動的に呼び出すことを検討する必要があります。

DECLARE @db sysname = N'db1';

DECLARE @exec nvarchar(max) = QUOTENAME(@db) + N'.sys.sp_executesql',
        @sql  nvarchar(max) = N'EXEC dbo.procedurename;';

EXEC @exec @sql;

そして、うまくいけば、最終的な目標は、SSMSでこのコードをすべて実行することではなく、SSMSが次のコンテキストで実行される@dbようにすることです。


これは素晴らしいです。AaronBertrandに感謝します。いいえ、最終的な目標は、SSMSでこのコードをすべて実行して、SSMSが@dbのコンテキストに入るようにすることではありません
Mazhar

2

dynamicSQLは実際にはインラインで実行されている場合でも、コードの残りの部分とは別のエンティティで具体的にインラインで実行されるわけではありません。

コードを実行するSET @sql = N'Use ' + @db + '; select DB_NAME(); select @@spid'と、現在のセットの一部で、アクティブデータベースを移動したことを示す結果が返されますが、同じ接続で実行されています。

インラインデータベースの選択を変更する場合は、次のような方法が最適です。

IF @db = 'db1'
    USE db1
ELSE IF @db = 'db2'
    USE db2

その見栄えもクリーンもないため、潜在的なデータベースごとに2行が必要ですが、ジョブは完了します(動的SQLで実行しないと、メインスレッドが変更されないという同じ問題が発生します)。

USEコマンドの使用は、プロシージャ/関数では禁止されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.