2017-04-04 32 views
3

存在着有关如何在SQL Server中使用F#与SQLCLR一些博客文章是有帮助的:http://richardminerich.com/2015/12/a-safer-way-to-use-f-with-sql-clr/http://thelastexpression.blogspot.com/2012/04/f-agents-and-sqlclr.htmlhttps://rojepp.wordpress.com/2011/08/03/f_on_sqlclr/Can the F# core libs be SQLCLR-approved? 和C#的方法:http://www.sqlservercentral.com/Authors/Articles/Solomon_Rutzky/294002/F#在一个合理的安全的方式SQLCLR和脚本组件

我想知道/希望随着时间的推移,那里有一篇博客文章,我还没有找到答案或者在这里找到答案,它解决了如何在SQLCLR中使用F#以使程序集可以使用Visual Studio(或其他工具)脚本化为十六进制,就像使用C#部署完成的一样(除了通过SQL Server Management Studio,我没有权限在服务器上安装代码),并且至少更多安全比使用'可信赖'或'不安全'。我之前编写过F#和大量的T-SQL,而我在Common Lisp中编写的原型(现在必须在SQL Server中生活)会更好地映射到F#(并使我比使用C#更快乐)。

+0

https://rojepp.wordpress.com/2011/08/03/f_on_sqlclr/也有关 – Joe

+0

这增加了讨论,以及:http://stackoverflow.com/questions/5653963/how-is-a-clr-table-valued -value-function-streaming(请参阅关于如何将FSharp.Core注册为程序集的注释) – Joe

+0

上面第一条注释中引用的代码:https://bitbucket.org/rojepp/blogsqlclr /src/c9ebace12da4552076955a5029f10f288f943e90/SqlClr/Deploy.sql?at=default&fileviewer=file-view-default – Joe

回答

3

我怀疑你的第一个链接(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.databasesTRUSTWORTHY目前OFF,或作者的代码不能在创建该登录之前,并授予该权限以它。

所以,我只是安装最新FSharp.Core –的构建4.1.2 –这里想这是我发现:

  1. 确认TRUSTWORTHY是通过OFF(即0):

    SELECT [name], is_trustworthy_on FROM sys.databases WHERE [database_id] = DB_ID(); 
    
  2. 尝试加载FSharp.CoreSAFE,只是为了看看它的工作原理:

    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.

  3. 尝试再次加载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权限。含义:违规可能是通过运行时验证而不是加载时验证发现的。我无法测试这部分,但我希望会发生错误。

  4. 如果出现关于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]; 
    
  5. 如果还需要您的大会被标记为UNSAFE,那么您可以在master创建DLL的非对称密钥,然后从非对称密钥基于密钥的登录,然后授予该基于密钥登录的UNSAFE ASSEMBLY权限。 (这里假设你的程序集是签名的 - 并且用密码保护)

  6. 当然,上述所有假设你可以将DLL放到服务器上,或者至少放到一个共享上,即SQL Server服务帐户有权访问,而且你确实提到想要通过十六进制字节来部署它。这应该可以做:

    1. 在Visual Studio中,“参考”下的“解决方案资源管理”,进入“属性” FSharp.Core并设置型号意识到True许可集Unsafe。这将导致发布过程将DLL包含在构建脚本中。
    2. 如果DLL已经在您的目标数据库中,那么它可能不会生成该组件的CREATE ASSEMBLY语句,因为发布脚本是渐进式更改。如果是这种情况,请转至项目属性,并在项目设置下,选中创建脚本(.sql文件)(如果尚未选中)的框。这将导致构建过程始终生成一个_Create.sql脚本,并且肯定会在FSharp.Core中声明CREATE ASSEMBLY
    3. CREATE ASSEMBLY [FSharp.Core] FROM 0x...语句显然将用于将程序集加载到目标数据库(即您的程序集也被加载到的位置)。
    4. 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上,唯一的区别是我使用的文件路径,而不是十六进制字节。

+2

非常感谢@srutzky查找并感谢你的优秀阶梯系列。 – Joe

+0

@Joe你很受欢迎,并感谢你的那些客气话。我很高兴人们从这些文章中获得一些东西(我将很快加入)。我已经更新了我的答案,现在我已经有机会进行测试了(至少就我所能做的而言,如果不做实际的F#项目,那么您的反馈将非常感谢:-)。 –

+0

杰出的分析,谢谢!我希望能很快尝试一下。 – Joe