T-SQLでデータベース名の変数を使用する方法


123

スクリプトのいくつかの場所でデータベース名を使用していて、すばやく変更できるようにしたいので、次のようなものを探しています。

DECLARE @DBNAME VARCHAR(50)
SET @DBNAME = 'TEST'

CREATE DATABASE @DBNAME
GO
ALTER DATABASE @DBNAME SET COMPATIBILITY_LEVEL = 90
GO
ALTER DATABASE @DBNAME SET RECOVERY SIMPLE 
GO

しかし、それは機能しません。それで、このコードを書く正しい方法は何ですか?

回答:


135

{SERVERNAME}プレースホルダーを使用して、スクリプト全体をテンプレート文字列に入れます。次に、以下を使用して文字列を編集します。

SET @SQL_SCRIPT = REPLACE(@TEMPLATE, '{SERVERNAME}', @DBNAME)

そしてそれを実行します

EXECUTE (@SQL_SCRIPT)

3年の間に、私のコードが機能しないことに誰も気づかなかったとは信じがたいです。

EXEC複数のバッチは使用できません。GOT-SQLステートメントではなく、バッチ区切り記号です。3つの個別の文字列を作成しEXEC、置換後にそれぞれに作成する必要があります。

で分割することによって単一のテンプレート文字列を複数の行に分割することでGO、何か「賢い」ことができると思います。ADO.NETコードでそれを行いました。

また、「サーバー名」という言葉はどこから入手したのですか。

これが私がテストしたばかりのコードです(そして機能します):

DECLARE @DBNAME VARCHAR(255)
SET @DBNAME = 'TestDB'

DECLARE @CREATE_TEMPLATE VARCHAR(MAX)
DECLARE @COMPAT_TEMPLATE VARCHAR(MAX)
DECLARE @RECOVERY_TEMPLATE VARCHAR(MAX)

SET @CREATE_TEMPLATE = 'CREATE DATABASE {DBNAME}'
SET @COMPAT_TEMPLATE='ALTER DATABASE {DBNAME} SET COMPATIBILITY_LEVEL = 90'
SET @RECOVERY_TEMPLATE='ALTER DATABASE {DBNAME} SET RECOVERY SIMPLE'

DECLARE @SQL_SCRIPT VARCHAR(MAX)

SET @SQL_SCRIPT = REPLACE(@CREATE_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)

SET @SQL_SCRIPT = REPLACE(@COMPAT_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)

SET @SQL_SCRIPT = REPLACE(@RECOVERY_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)

2
+1非常に優れたアプローチ...大量の作業から私を救っただけです、それはEXECUTE(@SQL_SCRIPT)でなければなりませんが、少なくともそれが私にとってはうまくいきました。
再作成、2011

2
ただし、エスケープには注意が必要です。
usr

4
SYSNAME可能なすべてのデータベース名を処理するためにVARCHAR(255)使用QUOTENAMEするよりも適切なデータ型です(名前のソースに応じてSQLインジェクションを防止するため)
Martin Smith

1
CREATE SCHEMAを使用して他のデータベースで使用したい場合、機能しませんUSE {DBNAME}。スキーマが間違ったデータベースに作成される; /
Bomberlt 2015年

103

sqlcmdこのためのモードを使用することもできます(Management Studioの[クエリ]メニューで有効にします)。

:setvar dbname "TEST" 

CREATE DATABASE $(dbname)
GO
ALTER DATABASE $(dbname) SET COMPATIBILITY_LEVEL = 90
GO
ALTER DATABASE $(dbname) SET RECOVERY SIMPLE 
GO

編集:

このMSDNの記事をチェックして、SQLCMDツールを介してパラメーターを設定してください。


1
このメソッドはすでに宣言された変数をどのように使用できますか?「TEST」の代わりに@dbNameを追加できますか?私は試しましたが、うまく
いき

1
@syclee TSQL変数?スクリプトがサーバーに送信される前に、sqlcmd置換は実行されません。
マーティン・スミス

@MartinSmithこんにちは、OUTPUTコマンドとしてdb名が必要です。では、SQLCMDを使用してどうすればよいですか?
Kunal Kakkad

12

残念ながら、その形式の変数を使用してデータベース名を宣言することはできません。

達成しようとしていることについては、EXEC()ステートメント内にステートメントをラップする必要があります。だからあなたは次のようなものを持っているでしょう:

DECLARE @Sql varchar(max) ='CREATE DATABASE ' + @DBNAME

次に電話します

EXECUTE(@Sql) or sp_executesql(@Sql)

SQL文字列を実行します。


EXECストアドプロシージャを探します。この場合EXECUTEは必要です。
Bob Blogge 2013

2
実際、お詫びする必要があります。それは判明EXECしてEXECUTE同じです。で失敗しEXEC、成功した後に私は声明を出しましたEXECUTE。明らかに私の本当の問題はどちらとも無関係でした。
Bob Blogge 2013

2
本番環境ではこれを行わないでください。
Magic Octopus Urn

@MagicOctopusUrnは古い投稿と非常にコメントが異なりますが、なぜ私は知りませんか?要件固有ではありませんか?
厳しい

@MagicOctopusUrnそれは注射の可能性のためですか?
アイザックリーフマン、

5

create tableステートメントでは変数を使用できません。私が提案できる最良のことは、クエリ全体を文字列として記述し、それを実行することです。

このようなものを試してください:

declare @query varchar(max);
set @query = 'create database TEST...';

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