我有一系列常量函数来简化编程和阅读我的一些SQL查询。例如,
对于给定的狗品种, dbo.CONST_DogBreed(NVARCHAR(MAX))
将返回INT
。例如,dbo.CONST_DogBreed('Labrador')
可能会返回12
。
我的问题是,如果我在查询中使用常量调用此函数,它会重复评估它还是会意识到它是一个常量而只评估它一次?所以,如果我这样做:
SELECT * FROM Dogs
WHERE [DogType] = dbo.CONST_DogBreed('Labrador')
是否每次评估dbo.CONST_DogBreed('Labrador')
?我意识到这里的解决方案是在上面的变量中声明我想要的值,但如果它不必要,我不愿意。
即。必须在每个查询的顶部执行此操作:
DECLARE @LabradorBreed INT = dbo.CONST_DogBreed('Labrador');
SELECT * FROM Dogs
WHERE [DogBreed] = @LabradorBreed
在写这个问题的一些研究之后,它似乎可能是基于该函数是否是确定性的。如果是这样,我如何确保我的功能是确定性的?它会为我做吗?有几个sql问题指定了Deterministic和其他一些使用Schema Binding之类的东西。由于我的const函数不使用任何模式,我认为模式绑定是不必要的。
所以我想在这项研究之后,它归结为:我如何确保我的功能是确定性的?
答案 0 :(得分:4)
数据库引擎自动分析Transact-SQL的主体 函数并评估函数是否是确定性的。对于 例如,如果函数调用其他函数 非确定性的,或者如果函数调用扩展存储 程序,然后数据库引擎将该功能标记为 非确定性。对于公共语言运行时(CLR)函数, 数据库引擎依赖于函数的作者来标记 使用SqlFunction自定义函数作为确定性函数 属性。
...
您需要将WITH SCHEMABINDING添加到用户定义函数的标头中 使其适用于"确定性"标签
https://technet.microsoft.com/en-us/library/ms187440(v=sql.105).aspx