如果我在SQL查询中调用一个函数,它会在每一行上进行评估吗?

时间:2016-12-20 18:22:54

标签: sql sql-server tsql sql-server-2012

我有一系列常量函数来简化编程和阅读我的一些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函数不使用任何模式,我认为模式绑定是不必要的。

所以我想在这项研究之后,它归结为:我如何确保我的功能是确定性的?

1 个答案:

答案 0 :(得分:4)

  

数据库引擎自动分析Transact-SQL的主体   函数并评估函数是否是确定性的。对于   例如,如果函数调用其他函数   非确定性的,或者如果函数调用扩展存储   程序,然后数据库引擎将该功能标记为   非确定性。对于公共语言运行时(CLR)函数,   数据库引擎依赖于函数的作者来标记   使用SqlFunction自定义函数作为确定性函数   属性。

...

  

您需要将WITH SCHEMABINDING添加到用户定义函数的标头中   使其适用于"确定性"标签

https://technet.microsoft.com/en-us/library/ms187440(v=sql.105).aspx