我有几个 SQL 对象需要根据请求的所需状态采取替代操作。有没有办法创建可以传递给存储过程、表值函数并在查询中使用(不使用 CLR)的数据库级常量(枚举)?
CREATE PROCEDURE dbo.DoSomeWork(@param1 INTEGER, ..., @EnumValue myEnumType) AS ...;
然后使用它:
EXEC doSomeWork 85, ..., (myEnumType.EnumValue1 + myEnumType.EnumValue2);
哪里myEnumType
会保存一些枚举值。
在此过程中,我将能够使用@EnumValue
它并针对值进行测试myEnumType
以完成所需的工作。我会myEnumType
为我正在考虑的情况设置位掩码的值。
举一个简单的例子,考虑一个昂贵的过程,它需要一个巨大的数据集并将其缩减为一个更小但仍然非常大的数据集。在此过程中,您需要在该过程的中间进行一些调整,这将影响结果。假设这是基于减少中中间计算的某些状态来过滤(或反对)某些类型的记录。@EnumValue
of 类型myEnumType
可以用来测试这个
SELECT ...
FROM ...
WHERE (@EnumValue & myEnumType.EnumValue1 = myEnumType.EnumValue1 AND ...)
OR (@EnumValue & myEnumType.EnumValue2 = myEnumType.EnumValue2 AND ...)
OR ...
在不使用 CLR 的情况下,这些类型的数据库级别常量是否可以在 SQL Server 中使用?
我正在寻找可以作为参数传递给存储过程、函数等的数据库级枚举或一组常量。
您可以使用 XML 架构在 SQL Server 中创建枚举类型。
例如颜色。
这允许您使用类型的变量或参数
xml(dbo.ColorsEnum)
。如果您尝试添加不是颜色的东西
你得到一个错误。
像这样构建 XML 可能有点乏味,因此您可以例如创建一个也包含允许值的辅助视图。
并像这样使用它来创建枚举。
如果您想从 XML 模式动态创建视图,您可以使用此查询提取颜色。
枚举当然也可以用作函数和过程的参数。
由于您显然使用的是 SQL Server 2016,我想抛出另一个“可能的”选项 -
SESSION_CONTEXT
。Leonard Lobel 的文章,在 SQL Server 2016 中共享状态,提供
SESSION_CONTEXT
了一些关于 SQL Server 2016 中的新功能的非常好的信息。总结几个关键点:
作为测试,我创建了一个服务器登录触发器,它设置了一些
CONTEXT_SESSION
信息——其中一个SESSION_CONTEXT
设置为@read_only
.我以全新用户身份登录并能够提取
SESSION_CONTEXT
信息:我什至尝试更改“只读”上下文信息:
并收到一个错误:
关于登录触发器的重要说明(来自这篇文章)!
一个潜在的缺点是这会填充会话上下文实例范围(而不是每个数据库)。在这一点上,我能想到的唯一选择是:
Session_Context
-值对前面加上数据库名称来命名它们,以免在另一个数据库中导致相同类型名称的冲突。这并不能解决Session_Context
为所有用户预定义所有名称值的问题。EventData
(xml),您可以使用它来提取登录用户,并基于此,您可以创建特定Session_Context
的名称-值对。在 SQL Server 中,没有(尽管我记得 1998 年在 Oracle 包中创建常量并且有点怀念在 SQL Server 中使用它们)。
而且,我刚刚进行了测试,发现您甚至无法使用 SQLCLR 执行此操作,至少在它在所有情况下都可以使用的意义上。阻碍是对存储过程参数的限制。似乎您不能在参数名称中包含 a
.
或。::
我试过了:在这两种情况下,它甚至都没有通过解析阶段(使用 验证
SET PARSEONLY ON;
),原因是:另一方面,这两种方法都适用于用户定义的函数参数:
因此,您真正能做的最好的事情是使用 SQLCLR 让某些东西直接与 UDF、TVF、UDA(我假设)和查询一起使用,然后在需要与存储过程一起使用时分配给局部变量:
这是我在有机会获得实际枚举值时采用的方法(与查找值相反,查找值应该位于特定于其用法/含义的查找表中)。
关于尝试使用用户定义函数 (UDF) 来吐出“常量”/“枚举”值,我无法让它工作,要么将其作为存储过程参数传递:
返回“语法不正确”错误,SSMS 突出显示括号内的所有内容,即使我用数字替换字符串,或者如果没有要传入的参数则替换右括号。