T-SQL'de veritabanı adı için bir değişken nasıl kullanılır?


123

Veritabanı adını komut dosyamın birkaç yerinde kullanıyorum ve hızlı bir şekilde değiştirebilmek istiyorum, bu yüzden şuna benzer bir şey arıyorum:

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

Ama işe yaramıyor. Peki bu kodu yazmanın doğru yolu nedir?

Yanıtlar:


135

Tüm komut dosyasını {SERVERNAME} yer tutucularla birlikte bir şablon dizesine yerleştirin. Ardından dizeyi şunu kullanarak düzenleyin:

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

ve sonra çalıştır

EXECUTE (@SQL_SCRIPT)

Üç yıl içinde kodumun çalışmadığını kimsenin fark etmediğine inanmak zor !

EXECBirden fazla parti yapamazsınız . GObir toplu iş ayırıcısıdır, bir T-SQL ifadesi değildir. Üç ayrı dizge oluşturmak ve ardından ikameden sonra EXECher biri için gereklidir .

Sanırım tek bir şablon dizgesini bölerek birden çok satıra bölerek "akıllıca" bir şey yapılabilir GO; Bunu ADO.NET kodunda yaptım.

Ve "SERVERNAME" kelimesini nereden aldım?

İşte az önce test ettiğim (ve işe yarayan) bazı kodlar:

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 Çok güzel bir yaklaşım ... Beni bir ton işten kurtardın, thx ... Gerçi EXECUTE (@SQL_SCRIPT) olmalı, ya da en azından benim için işe yarayan buydu.
— respawned

2
Yine de kaçarken dikkatli olmalısın.
— usr

4
SYSNAMEtüm olası veritabanı adlarıyla başa çıkmak için (ve muhtemelen adın kaynağına bağlı olarak SQL enjeksiyonunu önlemek için) VARCHAR(255)kullanılması gerekenden daha uygun bir veri türü olacaktırQUOTENAME
— Martin Smith

1
CREATE SCHEMAKullanarak başka bir veritabanında istersem çalışmıyor USE {DBNAME}. Şema yanlış veritabanında oluşturuyor; /
— Bomberlt

103

Bunun için sqlcmdmodu da kullanabilirsiniz (bunu Management Studio'daki "Sorgu" menüsünde etkinleştirin).

:setvar dbname "TEST" 

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

DÜZENLE:

SQLCMD aracı aracılığıyla parametreleri ayarlamak için bu MSDN makalesine bakın.


1
bu yöntem önceden tanımlanmış değişkenleri nasıl kullanabilir? "TEST" yerine bir @dbName ekleyebilir misiniz? Denedim ve çalışmadım
— syclee

1
@syclee Bir TSQL değişkeni? Script sunucuya gönderilmeden önce sqlcmd değişiklikleri yapılmaz.
— Martin Smith

@MartinSmith Hey, db adını OUTPUT komutu olarak istiyorum. Peki SQLCMD kullanarak buna nasıl sahip olabilirim?
— Kunal Kakkad

12

Maalesef bu formattaki bir değişkenle veritabanı adlarını açıklayamazsınız.

Başarmaya çalıştığınız şey için, ifadelerinizi bir EXEC () ifadesi içine almanız gerekecek. Yani şöyle bir şeye sahip olursunuz:

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

Sonra ara

EXECUTE(@Sql) or sp_executesql(@Sql)

sql dizesini çalıştırmak için.


EXECsaklı bir yordamı arar. Bu durumda EXECUTEgereklidir.
— Bob Blogge

2
Aslında özür dilemem gerekiyor. Ortaya çıkıyor EXECve EXECUTEaynı. Başarısız olduktan EXECve başardıktan sonra açıklamayı yaptım EXECUTE. Açıkçası benim gerçek sorunum ikisiyle de ilgisizdi.
— Bob Blogge

2
Bunu üretimde yapmayın ... Hiç.
— Magic Octopus Urn

@MagicOctopusUrn eski gönderi ve çok yorum farklı ama neden olmasın merak ediyorum? gereksinime özel olmamalı mı?
— Sert

@MagicOctopusUrn Bu, enjeksiyon potansiyeli nedeniyle mi?
— Isaac Reefman

5

Tablo oluşturma deyiminde bir değişken kullanamazsınız. Önerebileceğim en iyi şey, tüm sorguyu bir dizge olarak yazmak ve onu çalıştırmaktır.

Bunun gibi bir şey dene:

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

exec (@query);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.