如果数据库中的多个存储过程和函数需要一个“常量”值,是否有一种标准方法可以在一个地方定义它,以便在任何地方都可用?
例如,假设我使用 xp_logevent
在 CATCH
当 RAISERROR
时阻止向事件日志写入内容发生,但我想根据 RAISERROR
将严重性分组为信息、警告和错误严重性。
我可以设置一个常数 EventSeverity
使得:
RAISERROR
严重性 = 0 然后 xp_logevent
是信息性的。 RAISERROR
严重性 <= EventSeverity
比xp_logevent
是警告。 RAISERROR
严重性 > EventSeverity
比xp_logevent
是错误。 警告和错误严重性之间的界限不太可能改变,但如果改变,我只想在一个地方改变它。
我想到了这些可能性:
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
有没有最佳实践方法来做到这一点?
最佳答案
在其他条件相同的情况下,为了性能,我会选择硬编码的 FUNCTION。为了安全起见,这个函数应该放在一个不同的 SCHEMA 中,比如 MyDatabase.CONF.SettingsFunc 而不是通常的 DBO;权限设置为此架构,因此只有管理员有权更改数据。
如果您需要为许多不同的用途集中各种配置设置,那么最后一种方法 (FUNCTION+TABLE) 将具有更大的吸引力,为您为每个用例创建一个索引。同样,这个“设置”表应该在一个受限制的模式中,不像函数,它可以保留在默认模式中以便于编码。
但是,如果必须使用默认模式,那么在这个“设置”表中配置一个“INSTEAD OF UPDATE”触发器就变得有趣了,这样用户就不会轻易更改数据;不要忘记后一种方法不能称为“安全”,因为用户仍然可以更改(或删除!)触发器。
关于sql - 在 SQL 中定义命名常量的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8442565/