2009-04-07 14 views
107

używam nazwy bazy danych w kilku miejscach w moim skryptu i chcę, aby być w stanie szybko zmienić, więc szukam czegoś takiego:Jak używać zmiennej dla nazwy bazy danych w T-SQL?

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 

Ale to nie działa. Jaki jest więc właściwy sposób napisania tego kodu?

+0

Dynamic SQL ..... –

Odpowiedz

114

Umieść cały skrypt w ciągu znaków szablonu z symbolami zastępczymi {SERVERNAME}. Następnie edytować ciąg przy użyciu:

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

a następnie uruchomić go z

EXECUTE (@SQL_SCRIPT) 

Trudno uwierzyć, że w ciągu trzech lat, nikt nie zauważył, że mój kod nie praca!

Nie możesz EXEC wielu partii. GO to separator wsadowy, a nie instrukcja T-SQL. Konieczne jest zbudowanie trzech oddzielnych łańcuchów, a następnie do EXEC po zmianie.

Przypuszczam, że można zrobić coś "sprytnego", dzieląc pojedynczy ciąg szablonów na wiele wierszy, dzieląc na GO; Zrobiłem to w kodzie ADO.NET.

A skąd otrzymałem słowo "SERVERNAME"?

Oto niektóre kodu, które po prostu testowane (i które działa):

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 Bardzo ładne podejście ... Właśnie uratowałeś mnie od mnóstwa pracy, thx ... Chociaż powinno to być EXECUTE (@SQL_SCRIPT), lub przynajmniej to, co sprawdziło się dla mnie. – reSPAWNed

+2

Trzeba jednak uważać na ucieczkę. – usr

+4

'SYSNAME' byłby bardziej odpowiednim typem danych niż' VARCHAR (255) 'również powinien używać' QUOTENAME', aby poradzić sobie ze wszystkimi możliwymi nazwami baz danych (i ewentualnie zapobiegać iniekcji SQL w zależności od źródła nazwy) –

5

Nie można użyć zmiennej w instrukcji tworzenia tabeli. Najlepszą rzeczą, jaką mogę zasugerować, jest napisanie całego zapytania jako napisu i wykonanie tego.

spróbować czegoś takiego:

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

exec (@query); 
9

Niestety nie można zadeklarować nazwy bazy danych o zmiennej w tym formacie.

Do tego, co próbujesz osiągnąć, będziesz musiał zawijać swoje instrukcje w instrukcji EXEC(). Więc trzeba było coś takiego:

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

następnie zadzwonić

EXECUTE(@Sql) or sp_executesql(@Sql) 

wykonać sql ciąg.

+0

'EXEC' szuka procedury przechowywanej. W tym przypadku potrzebna jest funkcja "EXECUTE". –

+0

Dzięki @BobBlogge - zaktualizowałem go. –

+2

Właściwie muszę przeprosić. Okazuje się, że "EXEC" i "EXECUTE" są takie same. Złożyłem oświadczenie po nieudanej próbie "EXEC" i powodzeniu z 'EXECUTE'. Chociaż oczywiście mój prawdziwy problem nie był związany z żadnym z nich. –

90

Można również użyć do tego trybu sqlcmd (umożliwiają to w menu "query" w Management Studio).

:setvar dbname "TEST" 

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

EDIT:

Sprawdź to MSDN artykuł ustawienie parametrów przy użyciu narzędzia sqlcmd.

+0

w jaki sposób ta metoda może wykorzystywać już zadeklarowane zmienne? Zamiast "TEST" możesz dodać @dbName? Próbowałem i nie działałem – syclee

+1

@syclee Zmienna TSQL? Żadne podstawienia sqlcmd nie są wykonywane przed wysłaniem skryptu na serwer. –

+0

@MartinSmith Hej chcę, aby nazwa db jako polecenie OUTPUT. Więc jak mogę to zrobić za pomocą SQLCMD? –

Powiązane problemy