我怀疑你的第一个链接(http://richardminerich.com/2015/12/a-safer-way-to-use-f-with-sql-clr/)所示的方法,因为它不直接显示FSharp.Core库的加载,因此目前尚不清楚的是,作者没有设置TRUSTWORTHY ON
为了至少让那部分工作。什么似乎非常可疑的是,在步骤5,非对称的基于密钥的登录被授予了错误的权限:
GRANT EXTERNAL ACCESS ASSEMBLY TO FSHARP_CLR_Login
授予EXTERNAL ACCESS ASSEMBLY
不不允许的组件设置到UNSAFE
。 即需要UNSAFE ASSEMBLY
权限。它可能写作后,复制/粘贴错误,但没有证据显示(即从sys.databases
)TRUSTWORTHY
目前OFF
,或作者的代码不能在创建该登录之前,并授予该权限以它。
所以,我只是安装最新FSharp.Core –的构建4.1.2 –这里想这是我发现:
确认TRUSTWORTHY
是通过OFF
(即0
):
SELECT [name], is_trustworthy_on FROM sys.databases WHERE [database_id] = DB_ID();
尝试加载FSharp.Core为SAFE
,只是为了看看它的工作原理:
USE [TestDB];
CREATE ASSEMBLY [FSharp.Core]
FROM N'C:\path\to\project\packages\FSharp.Core.4.1.2\lib\net45\FSharp.Core.dll'
WITH PERMISSION_SET = SAFE;
那收到以下错误:
Msg 6211, Level 16, State 1, Line 32
CREATE ASSEMBLY failed because type 'Microsoft.FSharp.Collections.FSharpMap`2' in safe assembly 'FSharp.Core' has a static field 'empty'. 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.
尝试再次加载FSharp.Core,但UNSAFE
:
USE [TestDB];
CREATE ASSEMBLY [FSharp.Core]
FROM N'C:\path\to\project\packages\FSharp.Core.4.1.2\lib\net45\FSharp.Core.dll'
WITH PERMISSION_SET = UNSAFE;
工程。但是,我没有将数据库设置为TRUSTWORTHY ON
,我也没有创建登录并授予它EXTERNAL ACCESS ASSEMBLY
权限。含义:违规可能是通过运行时验证而不是加载时验证发现的。我无法测试这部分,但我希望会发生错误。
如果出现关于UNSAFE
权限设置为本届大会的错误,那么你可以处理,没有诉诸设置TRUSTWORTHY ON
,但您将需要在主机和基于Certficate-登录创建证书:
USE [master];
CREATE CERTIFICATE [FSharpCert45]
FROM EXECUTABLE FILE =
N'C:\path\to\project\packages\FSharp.Core.4.1.2\lib\net45\FSharp.Core.dll';
CREATE LOGIN [FSharpLogin45] FROM CERTIFICATE [FSharpCert45];
GRANT UNSAFE ASSEMBLY TO [FSharpLogin45];
如果还需要您的大会被标记为UNSAFE
,那么您可以在master
创建DLL的非对称密钥,然后从非对称密钥基于密钥的登录,然后授予该基于密钥登录的UNSAFE ASSEMBLY
权限。 (这里假设你的程序集是签名的 - 并且用密码保护)
当然,上述所有假设你可以将DLL放到服务器上,或者至少放到一个共享上,即SQL Server服务帐户有权访问,而且你确实提到想要通过十六进制字节来部署它。这应该可以做:
- 在Visual Studio中,“参考”下的“解决方案资源管理”,进入“属性” FSharp.Core并设置型号意识到到
True
和许可集至Unsafe
。这将导致发布过程将DLL包含在构建脚本中。
- 如果DLL已经在您的目标数据库中,那么它可能不会生成该组件的
CREATE ASSEMBLY
语句,因为发布脚本是渐进式更改。如果是这种情况,请转至项目属性,并在项目设置下,选中创建脚本(.sql文件)(如果尚未选中)的框。这将导致构建过程始终生成一个_Create.sql脚本,并且肯定会在FSharp.Core中声明CREATE ASSEMBLY
。
- 这
CREATE ASSEMBLY [FSharp.Core] FROM 0x...
语句显然将用于将程序集加载到目标数据库(即您的程序集也被加载到的位置)。
这CREATE ASSEMBLY [FSharp.Core] FROM 0x...
语句将也是你的票,创建对象master
如下:
USE [master];
CREATE ASSEMBLY [FSharp.Core]
FROM 0x4D....
WITH PERMISSION_SET = UNSAFE;
CREATE CERTIFICATE [FSharpCert45]
FROM ASSEMBLY [FSharp.Core];
DROP ASSEMBLY [FSharp.Core];
CREATE LOGIN [FSharpLogin45] FROM CERTIFICATE [FSharpCert45];
GRANT UNSAFE ASSEMBLY TO [FSharpLogin45];
这为我工作的SQL Server 2012上,唯一的区别是我使用的文件路径,而不是十六进制字节。
https://rojepp.wordpress.com/2011/08/03/f_on_sqlclr/也有关 – Joe
这增加了讨论,以及:http://stackoverflow.com/questions/5653963/how-is-a-clr-table-valued -value-function-streaming(请参阅关于如何将FSharp.Core注册为程序集的注释) – Joe
上面第一条注释中引用的代码:https://bitbucket.org/rojepp/blogsqlclr /src/c9ebace12da4552076955a5029f10f288f943e90/SqlClr/Deploy.sql?at=default&fileviewer=file-view-default – Joe