傳統關係型數據庫中,同一會話內多條 SQL 語句間共享信息,應用程序需手動在本地變量間搬運數據;觸發器、視圖等數據庫內部對象更無法訪問會話上下文。開發者被迫在應用層添加邏輯傳遞狀態,增加複雜度並引入安全隱患。
DB2 9.5 引入全局變量,作為一種新型數據庫對象,定義存於系統編目,值具備會話隔離性:每個會話擁有私有副本,互不干擾。無需應用代碼即可實現 SQL 語句間、會話與數據庫內部對象(觸發器/視圖/函數)間的狀態共享。
CREATE VARIABLE schema.var_name data_type DEFAULT expr;
-- 範例
CREATE VARIABLE mySchema.defaultPrinter VARCHAR(30) DEFAULT 'Printer001';
CREATE VARIABLE loginTime TIMESTAMP DEFAULT CURRENT TIMESTAMP;
CREATE VARIABLE schema1.gvDeptno INTEGER DEFAULT
((SELECT deptno FROM hr.employees WHERE empUser = SESSION_USER));
DROP VARIABLE schema.var_name;
-- 若被函數/觸發器/視圖引用則不可刪除
-- 讀取
VALUES schema.var_name;
SELECT * FROM tab WHERE col = schema.var_name;
EXEC SQL VALUES schema.var_name INTO :host_var;
-- 修改
SET schema.var_name = 'NewValue';
SELECT COUNT(*) INTO schema.activeEmployees FROM hr.employees WHERE active = 'Y';
CALL proc(..., OUT schema.var_name);
問題:維護窗口需插入歷史數據,但觸發器 validate_t 禁止 ORDER_DATE 超過 7 天。傳統做法:鎖表 → 刪觸發器 → 維護 → 重建觸發器 → 解鎖,風險高、停機長。
全局變量方案:
CREATE VARIABLE maint.bypassTrigger CHAR(1) DEFAULT 'N';CREATE TRIGGER validate_t
BEFORE INSERT ON T
REFERENCING NEW AS N
FOR EACH ROW
WHEN (N.ORDER_DATE < CURRENT TIMESTAMP - 7 DAYS AND maint.bypassTrigger = 'N')
SIGNAL SQLSTATE '38000' SET MESSAGE_TEXT = 'ORDER DATE TOO OLD';
SET maint.bypassTrigger = 'Y'; → 執行維護 → SET maint.bypassTrigger = 'N';優勢:無 DDL、無鎖表、會話隔離(僅當前會話生效)、瞬時生效/回滾。