Wil*_*Cau 5 sql sql-server-2008
如果数据库中的多个存储过程和函数需要一个“常量”值,是否有一种标准方法可以在一个地方定义它,以便在任何地方都可用?
例如,假设我使用xp_logeventinCATCH块在发生时将某些内容写入事件日志RAISERROR,但我想根据严重性将严重性分为信息性、警告性和错误性RAISERROR。
我可以设置一个常量EventSeverity,使得:
RAISERROR严重性 = 0,则xp_logevent是信息性的。RAISERROR严重性 <= EventSeveritythanxp_logevent是警告。RAISERROR严重性 > EventSeveritythanxp_logevent是错误。警告和错误严重性之间的界限不太可能改变,但如果改变,我只想在一个地方改变它。
我想到了这些可能性:
使用“ @@variable ”来存储值。
缺点:强制执行顺序,变量必须在其他过程和函数访问之前声明和设置。更改值意味着更改代码。
DECLARE @@EventSeverity INT = 9
...
BEGIN CATCH
IF ERROR_SEVERITY() < @@EventSeverity
...
ELSE
...
END CATCH
Run Code Online (Sandbox Code Playgroud)使用函数返回值。
缺点:改变值意味着改变代码。
CREATE FUNCTION dbo.EventSeverity()
RETURNS INT
AS
BEGIN
RETURN 9
END
...
BEGIN CATCH
IF ERROR_SEVERITY() < dbo.EventSeverity()
...
ELSE
...
END CATCH
Run Code Online (Sandbox Code Playgroud)使用“设置”表来存储值。
缺点:访问开销高。难以在代码中访问。难以用作参数。用户可以更改值。
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
Run Code Online (Sandbox Code Playgroud)使用带有功能的“设置”表来简化访问。
缺点:开销大。用户可以更改值。
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
Run Code Online (Sandbox Code Playgroud)有没有最佳实践方法来做到这一点?
在其他条件相同的情况下,为了性能,我会选择硬编码的 FUNCTION。为了安全起见,这个函数应该放在一个不同的 SCHEMA 中,比如 MyDatabase.CONF.SettingsFunc 而不是通常的 DBO;将此模式设置为权限,因此只有管理员有权更改数据。
如果您需要为许多不同的用途集中各种配置设置,那么最后一种方法(函数+表)将具有更大的吸引力,只要您为每个用例创建一个索引。同样,这个“设置”表应该处于受限模式中,与函数不同,函数可以保留在默认模式中以便于编码。
但是,如果必须使用默认模式,那么在此“设置”表中配置“INSTEAD OF UPDATE”触发器就变得很有趣,这样用户就不会轻易更改数据;不要忘记后一种方法不能称为“安全”,因为用户仍然可以更改(或删除!)触发器。