3

現在、ストアド プロシージャでクエリを実行しているリンク サーバーがあります。現在、クエリは正常に機能していますが、このクエリはコードのブランチごとに変更する必要があります。クロス サーバー クエリで呼び出しているデータベース名を取得するための最適な方法を知りたいです。

例: サーバー A にはサーバー B へのリンクがあります。サーバー A には 3 つのデータベースが含まれています。SRV_A.DB1_DEV、SRV_A.DB2_Trunk、SRV_A.DB3_Prod それぞれが対応するサーバー B にリンクされています... SRV_B.DB1_DEV、SRV_B.DB2_Trunk、SRV_B.DB3_Prod

サーバー A の各データベースには、同じストアド プロシージャがあります。sproc で変更されるのは、クロスサーバーの選択だけです。したがって、SRV_A.DB1_Dev の sproc には次のような選択があります。

SELECT foo FROM [SRV_B].[DB1_DEV].[foo_table] WHERE bar = 1 

一方、トランク ブランチのストアド プロシージャは次のようになります。

SELECT foo FROM [SRV_B].[DB2_Trunk].[foo_table] WHERE bar = 1

上記のすべてのブランチに DB をデプロイする VS プロジェクトが必要なので、データベース名を動的に入力できるようにしたいと考えています。私が思いついた解決策は、CHARINDEX 関数で一連の IF チェックを使用してから、次のように動的 SQL でクエリを作成することです。

DECLARE @dSql NVARCHAR(4000);
DECLARE @databaseName NVARCHAR(100) = DB_NAME();
DECLARE @tableName NVARCHAR(100);
IF SELECT CHARINDEX('Dev', @databaseName, 0)
    SET @tableName = '[SRV_B].[DB1_DEV].[foo_table]
    ...Same if & set for Trunk
    ...Same if & set for Prod
SET @dSql = 'DECLARE @retID INT;SELECT foo FROM ' + @tableName 
+ ' WHERE bar = 1';SET @retID = SELECT SCOPE_IDENTITY()'
EXEC(@dSQL);

より良い解決策があると想像する必要がありますが、誰かが私を助けることができれば、それは大歓迎です。外からのショットでこれが最善の方法である場合は、私にも知らせてください。

ありがとう、ジェームズ

4

2 に答える 2

5

この問題を解決する 1 つの方法は、リンク サーバー名を同義語でラップして抽象化することです。ターゲット テーブル名の余分な部分に注意してください
。クロスサーバー クエリには 4 つの部分からなる名前が必要です。これはタイプミスだと思います。質問で、それfoo_tabledboスキーマにあります

CREATE SYNONYM dbo.syn_foo_table
FOR [SRV_B].[DB1_DEV].[dbo].[foo_table]

これは、コード内で次のように参照できます。

SELECT foo FROM dbo.syn_foo_table WHERE bar = 1 

次に、展開スクリプトをカスタマイズして、環境の正しいサーバー/データベースを指すシノニムを作成する必要があります。これは、上で概説したものと同様の動的 SQL プロセスを使用できますが、(実行ごとではなく) デプロイ時に 1 回だけ実行する必要があります。

SQLCMD(AFAIK)VSプロジェクトはSQLCMDデータベースオブジェクトの展開に使用されるため、別の可能な解決策は、ストアドプロシージャスクリプトでパラメーターを使用することです。
この機能により、フォーム内の変数を使用して SQL スクリプトをパラメーター化できます$(variablename)-あなたの場合:

SELECT foo FROM [SRV_B].[$(dbname)].[foo_table] WHERE bar = 1 

変数の値は、環境変数を使用して設定するか、-vスイッチを使用して引数としてコマンドに渡すことができます。詳細については、SQLCMD上記の MSDN リンクを参照してください。

于 2012-04-16T08:53:13.323 に答える
0

上記のように環境変数の組み合わせを db-name に使用でき、次のクエリを使用して SRV 名も動的に生成できました。

DECLARE @ServerName NVARCHAR(100);
SET @ServerName = (SELECT name FROM sys.servers WHERE server_id = 1)
于 2012-04-17T01:41:32.330 に答える