Bạn sẽ phải sử dụng SQL động nếu bạn muốn thực hiện nó một cách động như vậy. Có nghĩa là bất kỳ điều gì bạn muốn thực thi trong ngữ cảnh của DB đó, bạn cũng cần phải đưa vào câu lệnh SQL động.
tức là giả sử bạn muốn liệt kê tất cả các bảng trong MainDB:
Điều này sẽ không hoạt động, vì câu lệnh USE nằm trong ngữ cảnh khác - khi EXECUTE đó đã chạy, SELECT sau sẽ KHÔNG chạy trong cùng ngữ cảnh đó và do đó sẽ không chạy trong MainDb (trừ khi kết nối đã được đặt thành MainDb)
DECLARE @DatabaseName NVARCHAR(MAX)
SET @DatabaseName = 'MainDb'
EXECUTE('USE ' + @DatabaseName) -- SQL injection risk!
SELECT name FROM sys.tables
Vì vậy, bạn cần phải làm:
DECLARE @DatabaseName NVARCHAR(MAX)
SET @DatabaseName = 'MainDb'
EXECUTE('USE ' + @DatabaseName + ';SELECT name FROM sys.tables') -- SQL injection risk!
Tất nhiên, bạn cần phải rất cẩn thận với SQL injection, mà tôi chỉ cho bạn đến liên kết trong câu trả lời của Barry.
Để ngăn SQL Injection, bạn cũng có thể sử dụng hàm QUOTENAME (), hàm này bao bọc tham số trong dấu ngoặc vuông:
DECLARE @DatabaseName sysname = 'MainDb'
, @SQL NVARCHAR(MAX);
SET @SQL = N'USE ' + QUOTENAME(@DatabaseName);
PRINT(@SQL);
-- USE [MainDb]
EXECUTE(@SQL);