4

我在单个数据库中安装了一组自定义 CLR 函数。当我需要在另一个数据库的查询/视图/过程中使用这些函数时,我只需通过三部分名称引用它们[db].[schema].[function](),它就可以正常工作。

但是由于错误,我不能在计算列中使用它们4120 A user-defined function name cannot be prefixed with a database name in this context

当然,使用两部分名称在同一数据库上添加计算列是没有问题的[schema].[function]()

任何想法如何解决这个问题?也许我可以在每个其他数据库中创建某种“快捷方式”函数来引用“原始”函数?或者我是否可以将这些函数安装在一个系统数据库中,使我能够仅使用函数的名称来调用函数,就像left()or一样substring()

现在,我用来更新和安装新函数的脚本在我需要这些函数的每个数据库以及modeldb 中执行相同的操作。但我希望有更优雅的方式来做到这一点。

4

2 回答 2

2

没有更优雅的方法可以做到这一点。计算列不能依赖于外部函数(即使您将其隐藏在同义词后面,这似乎是您所追求的那种“快捷方式”函数) - 问题是模式稳定性不能被交叉破坏 -数据库关系——当数据库离线、single_user 或被删除时会发生什么?这类似于外键不能引用另一个数据库中的表并且表不能属于另一个数据库中的模式的原因。

您已经知道不能使用由 3 部分组成的名称(在 SQL Server 2014 中,我得到一个不同的错误):

消息 207,级别 16,状态 1
列名“other_database_name”无效。

如果您尝试使用同义词来掩盖您的功能,您会得到:

消息 2788,级别 16,状态 2
同义词在模式绑定对象或约束表达式中无效。

因此,将您的函数部署到所有数据库,或预先计算值并手动插入和存储它们,而不是依赖于计算列。

于 2013-09-26T18:07:32.227 回答
1

我对一些约束检查使用了一种解决方法,在那里我遇到了同样的错误/问题。该逻辑也应该适用于计算列。

我将来自其他数据库的自定义函数封装在当前数据库中的一个新函数中,我将其命名为“cf_ref_SameFunctionName”。
它并不完美,但它使您能够将逻辑放在一个地方,即使您必须为所需的每个函数创建一个包装器。

优点:

  • 你的逻辑还在一处
  • 您可以更改基本功能,因为它没有被引用锁定。

缺点:

  • 与基本功能的关系被打破,这可能导致所有危险。
于 2014-10-10T12:58:22.337 回答