为其他数据库中的内部存储过程使用中央CLR存储过程/函数存储库来使用?


17

我想使用我在C#CLR中开发的代码在系统上的所有数据库中使用,这样我就不必将每个数据库设置为可信任并打开CLR并在每个数据库中保留一堆相同的代码。

从管理和安全的角度来看,有没有最佳方法?CLR功能是非常基本的功能,例如字符串分隔符,电子邮件验证,URL编码/解码,base64等。我希望每个数据库中只有dbo模式才能访问这些功能。

  1. 有没有简单的方法可以做到这一点?
  2. 另外我也不清楚CLR dll是否被嵌入,是否移动数据库,是否带有标签,或者是否也必须移动dll。

谢谢


1
好的听起来不错。只要我没有听到关于这个问题的死寂中的声。总是对stackoverflow感到幸运
Alex Erwin 2012年

1
dba.se的狂躁程度不如SO,但我相信您会在一天左右的时间里对此类问题得到足够的关注。你愿意忍受那么长时间吗?
杰克·道格拉斯

大声笑,忍耐是一种美德。我有很多问题,我想,MS会解决这个问题。如果您是一个SQL Server主机,希望公开一些有用的功能,但又不希望服务器对CLR完全开放怎么办?
亚历克斯·欧文

Answers:


8

在我们公司,我们有准确的设置。创建CLR程序集时,该程序集的二进制表示形式存储在创建该程序集的数据库中。如果您随时随地移动数据库,这将使您可以随身携带该程序集(甚至将其脚本化)。

几个月前,我们的数据中心被洪水淹没-充满了数台服务器。重建它们时,我只使用了前一天晚上备份的数据库的备份。到目前为止,我们还没有任何问题..(触摸木头!)

从安全角度来看,我不确定这是正确的做法,但是我们授予对CLR procs等的访问权限的方式是在共享数据库中创建一个角色,然后将其他数据库中的用户添加到该角色中。然后,该角色被授予在CLR proc上执行的权限。

如果CLR试图做一些事情,例如访问数据库所包含的数据库外部的资源,则可能会出现访问问题,但是您可以在创建程序集时在程序集上设置权限。以下链接提供了有关权限的更多信息,但我在这里无法解释:

http://msdn.microsoft.com/en-us/library/ms345101.aspx

希望对您有帮助。


6

程序集二进制文件以blob形式存储在数据库中,因此可以随数据库一起携带。仅在实例上启用CLR -没有针对该数据库的特定设置。

无论如何,您为什么要尝试这样做?

(我并不是要争辩;我只是想听听涉及的动机,因为也许可以用其他满足您需求的方法来解决问题。)


除了将程序集放在共享数据库中之外,没有其他方法可以轻松地做到这一点。

话虽如此,我认为采用以数据库为中心的体系结构是有利的,除非在特殊情况下有非常令人信服的理由进行集中化。原因是将程序集(或与此相关的任何内容)置于数据库之外会在您的环境中创建依赖项。这恰恰是Microsoft从SQL Server 2012开始针对包含数据库创建的相反方法。

  • 当您开始需要使用诸如复制或群集之类的功能时,这种依赖性可能会给部署增加巨大的复杂性,而且还会增加故障排除和故障转移过程。

  • 对于不熟悉该系统的人来说,这种体系结构不那么明显(即,它的自我发现性和自文档性都较低)。

  • 如果最终在不同的数据库中需要不同的安全性,或者涉及变化的任何事物,那么您将遭受很大的伤害。

  • 如果将这些数据库部署到客户那里(听起来好像不是,但出于完整性考虑,我会这样说),这将增加部署过程,维护和故障排除的复杂性。

  • 由于所有数据库都将共享此代码,因此,如果引入(或解决了)任何错误,则可能会破坏所有依赖数据库的应用程序。全面的单元测试将是绝对必要的。

如果您有多个需要相同功能的数据库,那么还有其他减少重复数据量的方法,我认为这是练习的重点。与数据库本身中的数据相比,即使是相当复杂的CLR程序集也不会占用太多的物理存储空间(几乎总是如此),因此除非您确实有成千上万个需要此功能的小型数据库,否则我不会将其视为有效的参数。部件。

您可以做的是为这些数据库修改部署过程的其他部分,以减少源重复。例如,从源代码管理中CLR代码的公共位置构建和部署程序集。或者,创建一个脚本,将同一程序集部署到数据库。尽可能使这部分事情自动化,这没什么大不了的。

我同意我的建议是折衷方案,因为仍然会有一些重复,但这必须与实现不遵循规定标准的体系结构所带来的负面影响相平衡。只有您才能确定适合您的环境的内容。


我认为您可能会破坏事情,但这是为了简化代码发布。这里没有开发人员大军。只有我。但是,我确实有其他人正在使用该数据库,因此除非从我定义的存储过程中使用过,否则我需要确保这些功能不可访问。
亚历克斯·欧文

1

正如其他两个答案正确指出的那样,程序集已加载到特定数据库中,并且不在系统范围内(尽管我相当确定该assembly_id系统范围内唯一的)。这意味着它们将与加载到的每个数据库一起备份和还原。

此外,enabled/ disabled设定CLR Integration(通过sp_configure全系统。附带说明,该设置仅适用于用户创建的 CLR功能。由于某些内置功能依赖于此功能,因此通常启用CLR。

就是说,尽管这里的其他两个答案确实给出了有效的要点,但是这些要点不是特定于SQLCLR的,并且没有提及做出此决定的特定于SQLCLR代码的因素。如果将代码部署到每个单独的数据库(假设您有多个数据库),则需要考虑内存问题,潜在的资源争用问题,潜在的与安全性相关的问题等。

在决定集中式数据库部署与单个数据库部署之间的区别时,我提供了应该牢记的全面清单,尤其是对于SQLCLR代码。而不是在此处重复列表,请参见以下答案(也在DBA.SE上):

如何从性能角度更好地使用CLR功能(在每个DB内重复或具有常规功能)?

另外,在相关说明中,我会质疑为什么要将任何数据库设置为TRUSTWORTHY ON。问题中提到的功能(即“字符串断开器,电子邮件验证,URL编码/解码,base64等”)在程序集中均可实现SAFE。除非绝对必要,否则您不应使用EXTERNAL_ACCESSUNSAFEperission_set值。如果需要一些功能,则这些功能应放在单独的程序集中,该程序集中仅包含SAFE代码,这样任何不执行数据访问并被标记为的标量函数都IsDeterministic = true将能够利用能够参与并行计划。

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.