トップ回答者
ストアド内でリンクサーバーの名前を動的に変えてSELECT INTOを実行したい

質問
-
こんにちは。お世話になります。
【環境】
・SQL Server2008 R2【やりたいこと】
1.サーバー側のSQL Server2008 R2に、ローカル側にあるSQL Server 2008 R2へのリンクサーバを作成します
2.ストアドの引数に1で作成したリンクサーバー名を渡します。
3.2の引数を用いて、SELECT INTOを実行したいと考えています。【現状】
DECLARE @sql VARCHAR(8000)
DECLARE @変数 VARCHAR(8000)
SET @変数 = '[リンクサーバー名]'SET @sql = 'SELECT * INTO [データベースB].[dbo].[テーブルB]'
SET @sql = @sql + 'FROM [データベースA].[dbo].[テーブルA]'
EXECUTE (@sql) AT [リンクサーバー名]
≪結果≫
ローカル側にテーブルBが作成される
SET @sql = 'SELECT * INTO [データベースB].[dbo].[テーブルB]'
SET @sql = @sql + 'FROM [データベースA].[dbo].[テーブルA]'
EXECUTE (@sql) AT @変数
≪エラー内容≫
メッセージ 102、レベル 15、状態 1、行 9
'@変数' 付近に不適切な構文があります。
SET @sql = 'SELECT * INTO ' + @変数 +'.[データベースB].[dbo].[テーブルB]'
SET @sql = @sql + 'FROM [データベースA].[dbo].[テーブルA]'
EXECUTE (@sql)
≪エラー内容≫
メッセージ 117、レベル 15、状態 1、行 1
オブジェクト の名前 'リンクサーバー名.データベース名.dbo.テーブル名' は、プレフィックスの最大数を超えています。最大数は 2 です。【質問】
ストアド内でリンクサーバーの名前を動的に変えて、SELECT INTOを行う方法を教えてください。
また、リンクサーバー以外の方法があれば教えてください。
よろしくお願いします。- 編集済み nyandaba 2011年11月24日 7:14
回答
-
適当に書いたコードなので…整理すると
SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];
↓
EXECUTE (N'SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];') AT [リンクサーバー名];
↓
EXECUTE (N'EXECUTE (N''SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];'') AT [リンクサーバー名];');
ですよね。このEXECUTEに渡す文字列(丸かっこの中)を作ればいいので
DECLARE @sql NVARCHAR(4000) = N'EXECUTE (N''SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];'') AT ' + @変数 + N';' EXECUTE (@sql);
でだめですか?
- 回答としてマーク nyandaba 2011年11月25日 4:53
すべての返信
-
私も以前に変数に関する質問をしていますが、EXECUTE文の「AT linked_server_name」に変数は使えません。EXECUTE文を組み立てるためにもう1段EXECUTE文が必要なようです。
DECLARE @execute VARCHAR(8000);
SET @execute = N'EXECUTE @sql AT ' + @変数 + N';';
EXECUTE @execute;# みたいな…
-
佐祐理さん、こんにちは。
回答をしていただき、ありがとうございます。教えていただいた内容を確認し、試してみたところ、以下のようなエラーが出ました。
DECLARE @sql VARCHAR(8000) DECLARE @変数 VARCHAR(8000) SET @変数 = '[リンクサーバー名]' SET @sql = 'SELECT * INTO [データベースB].[dbo].[テーブルB]' SET @sql = @sql + ' FROM [データベースA].[dbo].[テーブルA]' DECLARE @execute VARCHAR(8000); SET @execute = N'EXECUTE (@sql) AT ' + @変数 + N';'; EXECUTE @execute;
≪エラー内容≫
メッセージ 203、レベル 16、状態 2、行 16
名前 'EXECUTE (@sql) AT [リンクサーバー名];' は有効な識別子ではありません。@sqlを外に出して実行しても、同様のエラーが出ます。
SET @execute = N'EXECUTE (' + @sql + ') AT ' + @変数 + N';';
≪エラー内容≫
メッセージ 203、レベル 16、状態 2、行 16
名前 'EXECUTE (SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA]) AT [リンクサーバー名];' は有効な識別子ではありません。『EXECUTE (@sql) AT [リンクサーバー名]』で実行すると、ローカル側にテーブルBが作成されます。
どのように対処すればよろしいでしょうか。
教えてください。よろしくお願い致します。- 編集済み nyandaba 2011年11月25日 4:54
-
適当に書いたコードなので…整理すると
SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];
↓
EXECUTE (N'SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];') AT [リンクサーバー名];
↓
EXECUTE (N'EXECUTE (N''SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];'') AT [リンクサーバー名];');
ですよね。このEXECUTEに渡す文字列(丸かっこの中)を作ればいいので
DECLARE @sql NVARCHAR(4000) = N'EXECUTE (N''SELECT * INTO [データベースB].[dbo].[テーブルB] FROM [データベースA].[dbo].[テーブルA];'') AT ' + @変数 + N';' EXECUTE (@sql);
でだめですか?
- 回答としてマーク nyandaba 2011年11月25日 4:53
-
佐祐理さん、こんにちは。
回答をしていただき、ありがとうございます。先程のエラーの原因は、
EXECUTEに渡す文字列のSQLの部分をシングルコーテーションで括らなかったのが原因だったのですね。
教えていただいた内容で再度試してみたところ、エラー無く実行することができました。DECLARE @sql VARCHAR(8000) DECLARE @変数 VARCHAR(8000) SET @変数 = '[リンクサーバー名]' SET @sql = N'EXECUTE (' + N'''' SET @sql = @sql + N'SELECT * INTO [データベースB].[dbo].[テーブルB]' SET @sql = @sql + N' FROM [データベースA].[dbo].[テーブルA];' SET @sql = @sql + N'''' + N') AT ' + @変数 + N';' EXECUTE (@sql);
わかりやすく教えていただき、ありがとうございました。- 編集済み nyandaba 2011年11月25日 5:43