首先,我会说这个问题与 my previous post 有关。 .
但是,我会将所有内容移到此处以供引用。
我遇到的问题是我仍然收到错误:
Msg 6522, Level 16, State 1, Procedure PerfInsert, Line 0 [Batch Start Line 31] A .NET Framework error occurred during execution of user-defined routine or aggregate "PerfInsert": System.Security.SecurityException: Request failed. System.Security.SecurityException: at 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
最佳答案
您正在使用多线程,所以是的,程序集 100% 需要具有 PERMISSION_SET = UNSAFE
。
此外,由于您已经设置了非对称 key 和关联的登录名(感谢您这样做,并且不使用 TRUSTWORTHY ON
),因此您需要在设置程序集之前执行以下操作不安全:
USE [master];
GRANT UNSAFE ASSEMBLY TO [BrokcRetail];
然后:
USE [{db_containing_assembly_hopefully_not_master];
ALTER ASSEMBLY [PerfInsert] WITH PERMISSION_SET = UNSAFE;
或者,如果您创建基于非对称 key 的登录并首先授予其 UNSAFE ASSEMBLY
权限,那么您可以简单地使用 UNSAFE
而不是 SAFE
在 CREATE ASSEMBLY
语句中。
从 SQL Server 2017 开始,您需要在创建程序集之前创建非对称 key 和关联的登录名。非对称 key 和登录进入[master]
,而程序集可以进入任何数据库(包括[master]
,但通常最好不要在其中放置自定义代码)。
如果您已经在使用 SQL Server 2017 或更高版本,并且问题中显示的代码按照您执行它的实际顺序,那么我猜您已经将数据库设置为 TRUSTWORTHY ON
或禁用“CLR 严格安全”。否则,如果没有先创建基于签名的登录并授予 UNSAFE ASSEMBLY
权限,您根本就无法创建程序集。如果我的说法正确,您可以重新启用“CLR 严格安全性”和/或关闭该数据库的TRUSTWORTHY OFF
。
此外,正如我在您的相关问题(本问题中链接的问题)中指出的那样,您应该使用 SqlString
而不是 SqlChars
。 SqlString.Value
返回 .NET string
,而 SqlChars.Value
返回 char[]
。很久以前,人们将 SqlChars
与 NVARCHAR(MAX)
关联起来,将 SqlString
与 NVARCHAR(1-4000)
关联起来,但是这只是由于 Visual Studio/SSDT 在生成 DDL 来发布数据库项目时使用这些映射作为默认值。但它们之间从来没有任何技术/字符串映射。您可以将任一 .NET 类型与任一 T-SQL 数据类型一起使用。
此外,在 SQLCLR 中使用多线程时请务必小心(并进行大量测试)。
请访问SQLCLR Info获取与一般使用 SQLCLR 相关的更多资源。
相关帖子:
关于c# - 具有 CLR 函数的 System.Security.SecurityException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58646378/