我在一个数据库中安装了一组自定义CLR函数。当我需要在另一个数据库的查询/视图/过程中使用这些函数时,我只需通过三部分名称[db].[schema].[function]()
引用它们,它就可以正常工作。
但由于错误4120
A user-defined function name cannot be prefixed with a database name in this context
,我无法在计算列中使用它们。
当然,使用两部分名称[schema].[function]()
在同一数据库中添加计算列没有问题。
任何想法如何解决这个问题?也许我可以在每个其他引用“原始”数据库的数据库中创建某种“快捷方式”功能?或者我可以在一个系统数据库中安装这些函数,使我能够仅使用它的名称来调用函数,就像left()
或substring()
一样?
现在,我用来更新和安装新函数的脚本在我需要函数的每个数据库上执行相同的操作,在model
db中也是如此。但我希望有更优雅的方式来做到这一点。
答案 0 :(得分:2)
没有更优雅的方法来做到这一点。计算列不能依赖外部函数(即使你将它隐藏在synonym后面,这似乎是你所追求的那种“快捷方式”) - 问题是架构稳定性不能被跨数据库关系破坏 - 当数据库脱机,single_user或被丢弃时会发生什么?这类似于外键无法引用另一个数据库中的表而且表不能属于另一个数据库中的模式的原因。
您已经知道不能使用3部分名称(在SQL Server 2014中我得到了不同的错误):
消息207,级别16,状态1
无效的列名称'other_database_name'。
如果您尝试使用同义词掩盖您的函数,则会得到:
消息2788,级别16,状态2
在模式绑定对象或约束表达式中同义词无效。
因此,将您的函数部署到所有数据库,或预先计算值并手动插入和存储它们,而不是依赖于计算列。
答案 1 :(得分:2)
我使用了一些CONSTRAINT CHECK的解决方法,我遇到了同样的错误/问题。逻辑也适用于计算列。
我在另一个数据库中将自定义函数封装在当前数据库中的一个新函数中,我将其命名为" cf_ref_SameFunctionName"。
它并不完美,但它可以让你将逻辑放在一个地方,即使你必须为你需要的每个功能创建一个包装器。
<强>优点:强>
<强>缺点:强>