如果在數據庫中的多個存儲過程和函數中需要「常數」值,是否有一種標準方式將其定義在一個地方,以便在任何地方都可用?在SQL中定義一個命名常量的最佳方式是什麼?
例如,假設我用xp_logevent
在CATCH
塊時發生RAISERROR
寫的東西到事件日誌,但我想組基礎上,RAISERROR
嚴重程度嚴重到信息,警告和錯誤。
我可以設定的常數EventSeverity
使得:
- 如果
RAISERROR
嚴重性= 0則xp_logevent
用於提供信息。 - 如果
RAISERROR
嚴重性< =EventSeverity
比xp_logevent
是警告。 - 如果
RAISERROR
嚴重性>EventSeverity
比xp_logevent
是錯誤。
警告和錯誤嚴重程度之間的截斷不太可能改變,但如果它曾經做過,我只想在一個地方改變它。
我認爲這樣的可能性:
使用 '@@variable' 來存儲值。
- 優點:低訪問開銷。易於訪問的代碼。
缺點:強制執行順序,變量必須在其他過程和函數可以訪問之前聲明和設置。更改值意味着更改代碼。
DECLARE @@EventSeverity INT = 9 ... BEGIN CATCH IF ERROR_SEVERITY() < @@EventSeverity ... ELSE ... END CATCH
使用函數返回值。
- 優點:相當低的訪問開銷。易於訪問的代碼。
缺點:更改值意味着更改代碼。
CREATE FUNCTION dbo.EventSeverity() RETURNS INT AS BEGIN RETURN 9 END ... BEGIN CATCH IF ERROR_SEVERITY() < dbo.EventSeverity() ... ELSE ... END CATCH
使用 「設置」 表來存儲值。
- 優點:改變值意味着改變數據。
缺點:高訪問開銷。很難在代碼中訪問。很難用作參數。用戶可以更改值。
CREATE TABLE dbo.Settings ( Name VARCHAR(...), Value VARCHAR(...) ) ... INSERT INTO dbo.Settings (Name, Value) VALUES ('EventSeverity', CAST(9 AS VARCHAR)) ... BEGIN CATCH IF ERROR_SEVERITY() < (SELECT CAST(Value AS INT) FROM dbo.Settings WHERE Name = 'EventSeverity') ... ELSE ... END CATCH
使用 「設置」 表的功能,簡化訪問。
- 優點:易於改變價值。易於訪問的代碼。
缺點:高開銷。用戶可以更改值。
CREATE TABLE dbo.Settings ( Name VARCHAR(...), Value VARCHAR(...) ) ... INSERT INTO dbo.Settings (Name, Value) VALUES ('EventSeverity', CAST(9 AS VARCHAR)) ... CREATE FUNCTION dbo.EventSeverity() RETURNS INT AS BEGIN DECLARE @result INT SET @result = (SELECT CAST(Value AS INT) FROM dbo.Settings WHERE Name = 'EventSeverity') IF @result IS NULL SET @result = 9 RETURN @result END ... BEGIN CATCH IF ERROR_SEVERITY() < dbo.EventSeverity() ... ELSE ... END CATCH
有沒有一種最佳實踐的方式來做到這一點?
請參閱這裏:http://stackoverflow.com/questions/3370737/best-pattern-for-state-constants-in-sql-server-dbproj – StuartLC
如果它是一個特定於應用程序的常量,我會選擇使用dbo.settings方法,並確保表上的安全模型可以防止修改,從而滿足常量的完整性。 – Roman