我有一个sql clr,它有一些函数和存储过程。我让项目处于EXTERNAL_ACCESS
模式和签名密钥。 - 工作得很好。
我在项目中添加了另一个使用ICSharpcode.SharpZipLib
的函数。我最初得到版本的不兼容错误,我认为我按照另一篇文章的说明解决了。
该项目没问题,但现在我在项目的最后阶段(SQL服务器数据库项目)出现以下错误。这是在我的本地机器上,我有管理员权限。
Creating [ICSharpCode.SharpZipLib]...
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 6211, Level 16, State 1, Line 1 CREATE ASSEMBLY failed because type '<PrivateImplementationDetails>' in safe assembly 'ICSharpCode.SharpZipLib' has a static field '$$method0x6000014-1'. Attributes of static fields in safe assemblies must be marked readonly in Visual C#, ReadOnly in Visual Basic, or initonly in Visual C++ and intermediate language.
(47,0): SQL72045: Script execution error. The executed script:
CREATE ASSEMBLY [ICSharpCode.SharpZipLib]
AUTHORIZATION [dbo]
FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103003877BE5A0000000000000000E00002210B010B000000020000200000000000009E1B02000020000000200200000040000020000000100000040000000000000004000000000000000060020000100000000000000300408500001000001000000000100000100000000000001000000000000000000000004C1B02004F000000002002003804000000000000000000000000000000000000004002000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000A4FB0100002000000000020000100000000000000000000000000000200000602E7273726300000038040000002002000010000000100200000000000000000000000000400000402E72656C6F6300000C000000004002000
An error occurred while the batch was being executed.
感谢任何帮助! 谢谢, 萨蒂亚
答案 0 :(得分:0)
我想第一件事就是看你能不能做IcSharpcode.SharpZipLib
。如果没有,那么:
如果您有权访问IcSharpcode.SharpZipLib
的来源,则可以将静态更改为只读。
最后一个选项是使用PERMISSION_SET = UNSAFE
部署程序集。
答案 1 :(得分:-1)
与在OS上运行的CLR主机相比,在SQL Server中运行的CLR主机受到严格限制。限制的一个原因是应用程序域是跨会话共享的。因此,执行特定SQLCLR方法(无论是存储过程,函数,用户定义类型,用户定义聚合还是触发器)的每个人都在同一App Domain中的同一静态类中执行相同的方法。因此,静态类变量是共享资源,除非你非常小心并且故意使用它们,否则它们很容易导致竞争条件和奇怪(以及难以调试)的行为。
错误消息是关于此的,但它也有点误导,因为它提到SAFE
程序集不允许这样的事情。更确切地说,它是非UNSAFE
大会不允许这样的事情(即SAFE
和EXTERNAL_ACCESS
都没有。)
所以,正如Niels在他的回答中提到的,你可以将大会标记为UNSAFE
,它将加载并可能正常工作。但是,除非您知道如何使用该变量(以及任何其他标记为静态但尚未提及的变量),否则如果一个会话覆盖另一个会话仍在使用的值,则可能导致竞争条件。或者可能存在先前的值,可能会对下一个调用者产生负面影响。在尝试将程序集设置为UNSAFE
之前,您需要查看代码以确保这不是问题。
虽然不那么快速和简单,但您确实需要从更新代码开始,将这些静态变量标记为只读,并尝试重新编译以确保在整个代码中没有尝试写入该变量。如果代码的其他部分写入该静态变量,那么您需要重构代码或找到其他代码来执行相同的操作。我在几年前遇到过并选择使用DotNetZip作为我的SQL#项目,尽管我仍然需要对静态变量等内容进行微小的修改。