首先,我会说这个问题与my previous post有关。

但是,我将把所有内容移到这里以供参考。

我遇到的问题是我仍然收到错误:


  消息6522,级别16,状态1,过程PerfInsert,行0 [批处理开始行31]
  在执行用户定义的例程或聚合“ PerfInsert”期间发生.NET Framework错误:
  System.Security.SecurityException:请求失败。
  System.Security.SecurityException:
     在MiddleMan.MiddleMan.CreateCommand(SqlString tblString,SqlString featureName,SqlString connectionString,SqlString perfionConnectionString,SqlString logFile)
  。


即使我相信我已按照所有必要步骤正确设置了此设置。我什至可以验证SQL Server是否具有对文件目录的权限。

有人知道我还能检查一下丢失的部分吗?

还是我需要使其成为“不安全的”组件?

C#代码:

using Microsoft.SqlServer.Server;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;

    namespace MiddleMan
{
    public static class MiddleMan
    {
        [SqlProcedure(Name = "PerfInsert")]
        public static SqlInt32 CreateCommand(SqlString tblString, SqlString featureName, SqlString connectionString, SqlString perfionConnectionString, SqlString logFile)
        {
            Process compiler = new Process();
            compiler.StartInfo.FileName = "C:\\SQL Server C# Functions\\PerfionLoader\\PerfionLoader\\bin\\Release\\PerfionLoader.exe";
            compiler.StartInfo.Arguments = tblString.Value + " " + featureName.Value + " " + connectionString.Value + " " + perfionConnectionString.Value + " " + logFile.Value;
            //compiler.StartInfo.UseShellExecute = false;
            //compiler.StartInfo.RedirectStandardOutput = true;
            compiler.Start();
            return SqlInt32.Zero;
        }
    }
}


SQL代码:

CREATE ASSEMBLY PerfInsert
    AUTHORIZATION dbo
    FROM '\\bk-int-1\c$\SQL Server C# Functions\MiddleMan\MiddleMan\bin\Release\MiddleMan.dll'
    WITH PERMISSION_SET = SAFE
GO


CREATE ASYMMETRIC KEY [Brock.Retail_Brock.Retail_Brock]
  AUTHORIZATION [dbo]
  FROM EXECUTABLE FILE = '\\bk-int-1\c$\SQL Server C# Functions\MiddleMan\MiddleMan\bin\Release\MiddleMan.dll';

  CREATE LOGIN BrokcRetail
    FROM ASYMMETRIC KEY [Brock.Retail_Brock.Retail_Brock]


CREATE PROCEDURE PerfInsert
    (
        @tblString nvarchar(max)
        , @featureName nvarchar(max)
        , @connectionString nvarchar(max)
        , @perfionConnectionString nvarchar(max)
        , @logFiel nvarchar(max)
    )
    AS EXTERNAL NAME PerfInsert.[MiddleMan.MiddleMan].[CreateCommand]
GO

最佳答案

您正在使用多线程,因此是的,Assembly 100%需要具有PERMISSION_SET = UNSAFE

另外,由于已经设置了非对称密钥和关联的登录名(感谢您这样做并且不使用TRUSTWORTHY ON),因此在将Assembly设置为UNSAFE之前,需要执行以下操作:

USE [master];
GRANT UNSAFE ASSEMBLY TO [BrokcRetail];


然后:

USE [{db_containing_assembly_hopefully_not_master];
ALTER ASSEMBLY [PerfInsert] WITH PERMISSION_SET = UNSAFE;


或者,如果创建基于非对称密钥的登录名并首先授予其UNSAFE ASSEMBLY权限,则可以在UNSAFE语句中简单地使用SAFE代替CREATE ASSEMBLY

从SQL Server 2017开始,在创建程序集之前,您将需要创建非对称密钥和关联的登录名。非对称密钥和登录名进入[master],而Assembly可以进入任何数据库(包括[master],但通常最好不要在其中放置自定义代码)。

如果您已经在使用SQL Server 2017或更高版本,并且如果问题中显示的代码按照执行它的实际顺序执行,那么我想您已经将数据库设置为TRUSTWORTHY ON或已禁用“ “ CLR严格的安全性”。否则,您必须先创建基于签名的登录名并授予UNSAFE ASSEMBLY权限,才能完全创建部件。如果我对此表示正确,则可以重新启用“ CLR严格安全性”和/或对该数据库打开TRUSTWORTHY OFF

另外,正如我在您的相关问题(此问题中链接到的问题)中指出的那样,您应该使用SqlString而不是SqlCharsSqlString.Value返回.NET string,而SqlChars.Value返回char[]。很久以前,人们将SqlCharsNVARCHAR(MAX)关联,并且将SqlStringNVARCHAR(1-4000)关联,但这仅是由于Visual Studio / SSDT在生成DDL以发布数据库项目时将这些映射用作默认值。但是它们之间从来没有任何技术/字符串映射。您可以将.NET类型与T-SQL数据类型一起使用。

另外,在SQLCLR中使用多线程时,请谨慎操作(并进行大量测试)。

请访问SQLCLR Info,以获取与一般使用SQLCLR相关的更多资源。

相关文章:


System.Web in SQL Server CLR Function(在DBA.StackExchange上)
CREATE PROCEDURE gets “Msg 6567, Level 16, State 2” for SQLCLR stored procedure

10-05 19:29