在 SQL Server 儲存程序、觸發器或使用者定義函數中,**禁止使用 USE database_name** 切換資料庫內容。本文提供經驗證可行的 EXEC(...) 動態 SQL 繞過方案。
編譯器會在建立程序時檢查並拒絕 USE 陳述式。但某些系統程序 (如 sp_adduser) 必須在特定資料庫內容下執行,因此需要替代方案。
利用 EXEC('USE target_db; statement_list') 在子批次中暫時切換資料庫內容。**關鍵點:** 所有需在目標資料庫執行的陳述式必須包含在同一個 EXEC 字串內,因為資料庫內容切換僅在該動態批次執行期間有效。
CREATE PROCEDURE cs
AS
BEGIN
-- 在 sjdbmis 資料庫中查詢 txtplu 表
EXEC('USE sjdbmis; SELECT plucode FROM txtplu');
END;
GO
CREATE PROCEDURE cs
AS
BEGIN
-- 在 sjdbmis 中建立使用者
EXEC('USE sjdbmis; EXEC sp_adduser ''test''');
END;
GO
''。CREATE PROC test
AS
EXEC('USE pubs') EXEC sp_adduser 'test'; -- 注意:這裡第二個 EXEC 不在動態字串中,實測可能失敗
GO
-- 正確寫法:全部包在一個 EXEC 內
CREATE PROC test_correct
AS
EXEC('USE pubs; EXEC sp_adduser ''test''');
GO
sp_executesql 參數化。database.schema.object 直接跨庫存取 (不適用 sp_adduser 等內容敏感指令)。