我的一位开发人员编写了一个SQL函数,该函数的功能类似于VB.Net函数(LastIndexOf),并希望将其发布。我的问题是将其放入中央数据库而不是将其放入每个用户数据库的原因是什么?
开发人员试图将其放在sys模式中的主数据库上,这样他就不必限定来自用户数据库的调用...
但是我不确定将其集中到每个用户数据库的有效借口(显然不是主数据库)是什么?
我的一位开发人员编写了一个SQL函数,该函数的功能类似于VB.Net函数(LastIndexOf),并希望将其发布。我的问题是将其放入中央数据库而不是将其放入每个用户数据库的原因是什么?
开发人员试图将其放在sys模式中的主数据库上,这样他就不必限定来自用户数据库的调用...
但是我不确定将其集中到每个用户数据库的有效借口(显然不是主数据库)是什么?
Answers:
我更喜欢这样做:将函数放在实用程序数据库中,并在每个常规数据库中为其创建同义词。通过这种方式,您可以两全其美:
例如
USE UtilityDB;
GO
CREATE FUNCTION dbo.LastIndexOf(...) ...
GO
USE otherDB;
GO
CREATE SYNONYM dbo.LastIndexOf FOR UtilityDB.dbo.LastIndexOf;
GO
这对于CLR功能特别强大,因为更改/部署这些功能会产生额外的管理开销。
而且,这比使用master(并标记为系统对象,不能保证可向前移植)更可取。我很想知道您的开发人员期望如何在sys
架构中创建他的功能。
我确实了解到,在500个数据库中维护一个函数的多个副本并不比维护单个副本真正困难,但是拥有多个副本实际上仅在您确实有异常时才有好处(例如,客户端A希望其函数以不同的方式处理NULL,或者其他的东西)。在这种情况下,我会将同义词保留在所有其他数据库中,并仅在该数据库中引入该函数的特殊版本。
(当然,此功能假定该函数不依赖于客户端数据库中的任何数据访问,这肯定会使事情复杂化。)
我将不得不不同意亚伦(以及公认的答案)。
Aaron的方法是我喜欢处理“ DBA内容”(例如维护脚本)的方式。我永远不会希望通过用户数据库调用的库函数来做到这一点。
为什么?您将前往DLL Hell的数据库等效版本。
不兼容的版本
...在Windows 2000之前,Windows易受此影响,因为COM类表已在所有用户和进程之间共享。可以将一个DLL / EXE中的仅一个COM对象声明为在系统上具有特定的全局COM类ID。如果需要任何程序来创建该类的实例,那么它将获得当前集中注册的实现。结果,安装公共对象新版本的程序的安装可能会无意间破坏了先前安装的其他程序。
在运行.net 2.0应用程序的服务器上安装.net 4.5,会发生什么?没什么,您正在应用程序继续使用2.0框架。在托管3个应用程序数据库的服务器上更新您的LastIndexOf函数(作为对其中一个应用程序的升级的一部分),会发生什么?这三个现在都使用最新版本。
替代方法是SQL#采用的方法。它已安装到每个用户数据库的架构中,因此您可以安全地为Application-X升级数据库,而不必担心Application-Y的稳定性。
如果您在严格控制的变更管理环境中工作,则别无选择,如果不测试组件的所有使用者,就无法升级共享组件。如果您在“快速而轻松”的地方工作,则可以随意利用补丁/升级无意间破坏某些内容。
LastIndexOf
更改的功能有很大的危险,更不用说仅破坏某些应用程序/数据库的方式了。对于CLR或服务多个应用程序的真正的中央/复杂功能,这是一个更大的问题。(3)我的实际偏好是根本不将函数用于简单任务。