首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 取得目前資料庫名稱與跨批次全域變數技巧:系統函數與游標實作

     編輯:關於SqlServer

兩個經典 T-SQL 問題:(1) 如何在 SQL 陳述式中取得目前資料庫名稱?(2) 當 GO 批次分隔符切斷變數作用域時,如何跨批次保持計數器?本文提供原生系統函數與游標兩種解法,並說明適用場景。

問題一:取得目前資料庫名稱

✅ 方法 1:DB_NAME() — 最簡單、效能最佳

SELECT DB_NAME() AS CurrentDB;  -- 回傳目前連線的資料庫名稱
SELECT DB_NAME(DB_ID()) AS CurrentDB_V2;  -- 等效寫法

✅ 方法 2:原生函數 (SQL 2008+)

SELECT DB_NAME() AS CurrentDB;  -- 同方法 1
-- 系統檢視替代
SELECT NAME FROM SYS.DATABASES WHERE DATABASE_ID = DB_ID();

⚠️ 作者原文思路:SP_WHO + @@SPID (不推薦)

EXEC SP_WHO @@SPID;  -- 需解析結果集,效能差、權限需求高

結論:直接使用 DB_NAME(),無需查詢系統程序。

問題二:跨 GO 批次保持變數值

背景:GO 為 SSMS/工具的批次分隔符,非 T-SQL 關鍵字。每個批次編譯獨立,區域變數 (@Var) 在批次結束即釋放。

方案 A:使用暫存表保存狀態 (推薦,簡單高效)

-- 批次 1
CREATE TABLE #LoopState (Counter INT);
INSERT INTO #LoopState VALUES (0);
GO

-- 批次 2 (迴圈主體)
DECLARE @Cnt INT;
SELECT @Cnt = Counter FROM #LoopState;
WHILE @Cnt < 10
BEGIN
    -- 業務邏輯:如 ALTER TABLE #Temp ADD Col..., INSERT #Temp...
    SET @Cnt = @Cnt + 1;
    UPDATE #LoopState SET Counter = @Cnt;
    -- 若需再次 GO,此處可結束批次
END
GO

-- 批次 3 讀取最終值
SELECT Counter FROM #LoopState;  -- 10
DROP TABLE #LoopState;

方案 B:使用游標 (作者原文方案,適用複雜逐列邏輯)

-- 建立含計數器的暫存表
CREATE TABLE #Ctrl (ID INT IDENTITY, Cnt INT);
INSERT INTO #Ctrl (Cnt) VALUES (0);

-- 宣告游標
DECLARE Cur CURSOR LOCAL FORWARD_ONLY FOR SELECT Cnt FROM #Ctrl;
OPEN Cur;
FETCH NEXT FROM Cur INTO @Cnt;  -- @Cnt 為區域變數,但游標跨批次存活

-- 此處可插入 GO 分隔批次,游標與暫存表不受影響
GO

-- 後續批次繼續使用游標
FETCH NEXT FROM Cur INTO @Cnt;
-- ...
CLOSE Cur; DEALLOCATE Cur;

⚠️ 游標跨 GO 批次在某些工具版本可能失效,暫存表方案更穩健。

方案 C:SQLCMD 模式變數 (僅限 sqlcmd/SSMS SQLCMD 模式)

:SETVAR LoopMax 10
-- 批次 1
DECLARE @Max INT = $(LoopMax);
-- 批次 2 仍可讀取 $(LoopMax)

最佳實務建議

  • ✅ 能用單一批次解決就不拆分 GO,避免狀態管理複雜度。
  • ✅ 跨批次共享狀態首選 暫存表 (#Table) 或 全域暫存表 (##Table)。
  • ✅ 取得資料庫名稱永遠用 DB_NAME()。
  • ✅ 複雜部署腳本考慮使用 sqlcmd 變數或 PowerShell 協調。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved