Musiałbyś użyć dynamicznego SQL, jeśli chcesz to robić dynamicznie w ten sposób. Oznaczałoby to, że wszystko, co chcesz wykonać w kontekście tej bazy danych, musisz również uwzględnić w instrukcji dynamicznego SQL.
tzn. załóżmy, że chcesz wyświetlić listę wszystkich tabel w MainDB:
To nie zadziała, ponieważ instrukcja USE znajduje się w innym kontekście — po uruchomieniu EXECUTE następująca SELECT NIE będzie działać w tym samym kontekście, a więc nie będzie działać w MainDb (chyba że połączenie zostało już ustawione na GłównaDb)
DECLARE @DatabaseName NVARCHAR(MAX)
SET @DatabaseName = 'MainDb'
EXECUTE('USE ' + @DatabaseName) -- SQL injection risk!
SELECT name FROM sys.tables
Musisz więc zrobić:
DECLARE @DatabaseName NVARCHAR(MAX)
SET @DatabaseName = 'MainDb'
EXECUTE('USE ' + @DatabaseName + ';SELECT name FROM sys.tables') -- SQL injection risk!
Oczywiście trzeba być bardzo ostrożnym z wstrzykiwaniem SQL, dla którego odsyłam do linku w odpowiedzi Barry'ego.
Aby zapobiec wstrzyknięciu SQL, możesz również użyć funkcji QUOTENAME(), która otacza parametr w nawiasy kwadratowe:
DECLARE @DatabaseName sysname = 'MainDb'
, @SQL NVARCHAR(MAX);
SET @SQL = N'USE ' + QUOTENAME(@DatabaseName);
PRINT(@SQL);
-- USE [MainDb]
EXECUTE(@SQL);