为什么用户定义的标量函数需要模式?

Man*_*ngo 5 schema sql-server functions

创建用户定义的表函数或用户定义的过程时,可以按命名调用函数或过程。

但是,用户定义的标量函数要求您使用架构调用它:

select dbo.doit(data);
Run Code Online (Sandbox Code Playgroud)

我在其他 DBMS 中没有遇到过这种行为。为什么标量函数是这种情况,而其他函数则不然?

这不仅仅是病态的好奇心,而且我知道问为什么Microsoft 产品是无效的。

如果存在标量函数需要模式而不是其他模式的技术原因,那么值得了解。这不是其他 DBMS 的行为,但可能有技术原因导致这里出现这种情况。

小智 11

因为这是 Sybase/Microsoft 在实施它时决定的。-一匹无名的马

我认为当你调用任何没有模式的函数时,它只会查找系统函数或内置函数,如果你使用模式调用内置函数,SELECT dbo.getdate()它只会查找用户定义的函数。- biju-jose

问题是为什么使用标量函数而不是其他函数?

可能是因为当将标量函数引入产品时,他们可以从一开始就强制执行。由于会破坏现有代码的数量,他们无法返回并为其他对象强制执行它。出于同样的原因,他们宣布弃用没有终止符的语句,但实际上这可能永远不会发生。还要记住,模式前缀并不总是模式,它用于指示所有者。

我打算提出,如果您创建一个与(未来)内置函数共享名称的标量函数,解析器有必要区分您的意图。考虑SELECT doit()在 SQL Server 2017 中,然后在 SQL Server 2021 中,他们添加了一个名为doit().

在其他情况下(表值函数),解析器会得到更多关于它是什么的提示,因为它在FROM. 但这不再适用,因为在STRING_SPLIT()- 2016 年添加的情况下- 如果我有一个名为的函数,string_split()我可能会对任何行为变化感到惊讶。

你可以问各种“为什么”的问题。为什么有些ALTER DATABASE命令有SET <feature> ON而有些是SET <feature> = ON?为什么我们有NOWAITNO_WAITBACKUP TO NUL而不是NULL?各种历史的东西都存在,签到不复查,左手/右手。为什么通常是无关紧要的、未知的或不令人满意的。

无论如何,“为什么”真的很重要吗?知道解决了什么技术问题?我们不能告诉你为什么,你必须问微软。-亚伦-贝特朗


旁注:尽管您可以省略大多数对象的架构名称,但将架构前缀添加到所有使用的对象是更好的做法(使用 SQL Server 时)。如果不这样做,您可能会看到一些意外或不需要的行为。一个博客张贴关于这一点:坏习惯踢:避免模式前缀阿龙贝特朗-兰迪- vertongen