为什么在调用函数时必须使用模式前缀(dbo)?


9

当用户使用默认架构(dbo)映射时,我们可以选择[dbo]下的所有表而无需在架构前添加前缀。

如果存储过程在默认模式下,我们可以不带前缀地执行存储过程。

鉴于此,为什么我们需要在函数之前加上模式?

谢谢!

Answers:


11

那么,为什么我们可以调用在dbo下创建的不带前缀(模式)的函数呢?

有关UDF的在线图书文档中

在使用标量表达式的地方,可以调用标量值的函数。这包括计算列和CHECK约束定义。标量值函数也可以通过使用EXECUTE语句执行。标量值函数必须至少使用函数的两部分名称来调用

因此,这基本上是SQL Server开发团队设置的限制,我认为这是非常正确的。即使允许(出于对话目的),我仍将使用Schema前缀。

我始终支持使用架构名称,即使不添加它也可以使用。这是最佳做法,无论有多少冗余,所有“优秀”开发人员都将使用它。

我看到的另一个原因是,数据库引擎需要一些东西来区分类似系统功能getdate ()和用户定义的功能。如果允许您不使用模式名称调用函数,那么数据库引擎将如何区分用户创建的名为Getdate的函数或系统的GETDATE()函数。


那么为什么SP与之不同。如您所说,这可能是避免命名冲突。我刚刚在用户数据库中创建了一个SP“创建过程sp_help作为select getdate()select getdate()”,当我执行带有或不带有模式(dbo)的程序时,SQL Server均指系统SP。为什么它不执行我创建的SP。
Rajesh Ranjan

1
@rajeshRajan由于您具有sp_procname(在过程中添加了SP前缀),因此这将强制SQL Server首先在master数据库中查找已编译的计划,并且由于此proc存在于master数据库中,如果没有找到该proc,则将执行该操作。在主人那里,它将执行您的。永远不要创建带有前缀sp_的proc,因为它存在性能问题。
Shanky

我认为Shanky提到SQL Server开发团队设置的问题时,直接回答了“为什么”问题。您可能会问为什么这样做,以及为什么函数的行为与过程不一致,但是答案可能并不重要。
Michael J Swart

1
顺便说一句,无法测量以“ sp_”开头的过程对性能的影响。多年来一直不是问题。sp前缀可能仍然不是一个好主意,但是性能并不是原因。
Michael J Swart

10

另一个答案说明这是一个限制,而不是原因。

该要求并不总是正确的。标量UDF可以被EXEC-ed并仍然使用隐式分辨率(示例

我想这是为了避免命名冲突。

如果允许在不使用模式的情况下引用函数,那么创建自己的函数(恰好crypt_gen_random在2000或2005年被调用)的人会遇到升级到更高版本的问题,因为它在2008年成为内置函数的名称。

exec内置函数的用法没有任何歧义,因此不能这样称呼。


那么为什么SP与之不同。如您所说,这可能是避免命名冲突。我刚刚在用户数据库中创建了一个SP“创建过程sp_help作为select getdate()select getdate()”,当我执行带有或不带有模式(dbo)的程序时,SQL Server均指系统SP。为什么它不执行我创建的SP。
Rajesh Ranjan

3
@Rajesh。以sp_开头的对象具有特殊情况,以始终在master / resource数据库中查找。并且有文件记载,应避免使用此前缀。内置函数没有这样的约定。
马丁·史密斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.