sql - 是否可以找到用于在 SQL SERVER CLR 中加载程序集的原始路径?

标签 sql sql-server sqlclr

我对在 SQL Server 中使用程序集 CLR 非常陌生

我有一个包含很多这样的数据库 enter image description here

是否可以找到用于加载程序集的原始路径?

考虑到这是创建程序集的方式,我需要“来自”路径

CREATE ASSEMBLY ClassLibrary1 
from 'D:\DotNetTeam\SQLServer\ClassLibrary1.dll' 

我问这个问题是因为在服务器列表中找不到此程序集:a798b6eb4255719355458f3749073dc1b,并且被报告为不安全(我知道我必须对其进行签名,但为此我需要首先找到它)

我发现了另一个问题,但不是我需要的。 How to find the assembly registered in SQL Server?

更新

查询 sys. assembly_files 表,我注意到该记录存在,但不在左侧(对象资源管理器:程序集),我是否需要重新创建程序集?

select * 
from sys.assembly_files
where name like 'a79%'

enter image description here

此问题的解决方案也可能帮助您解决其中的任何问题
错误:

System.IO.FileLoadException: Could not load file or assembly 'ASSEMBLY_NAME, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)

System.IO.FileLoadException: Could not load file or assembly 'ASSEMBLY_NAME, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Exception from HRESULT: 0x80FC80F1

最佳答案

是的,但如果程序集是从文件系统上的 DLL 加载的,而不是通过提供 VARBINARY 文字/十六进制字节。当从外部 DLL 加载时(顺便说一句,我强烈推荐反对这种方法),原始路径存储在 sys. assembly_files 的 [name] 列中.

执行以下命令以显示任何潜在路径:

-- Change this to the assembly name or path to apply filter:
DECLARE @AssemblyName NVARCHAR(260) = '';
    
-- The content can be used to export the DLL:
SELECT asm.[name] AS [Assembly],
       afl.[name] AS [PathOrAltName],
       asm.[permission_set_desc],
       afl.[file_id],
       afl.[content]
FROM   sys.assembly_files afl
INNER JOIN sys.assemblies asm
        ON asm.[assembly_id] = afl.[assembly_id]
WHERE asm.[name] LIKE N'%' + @AssemblyName + N'%'
OR    afl.[name] LIKE N'%' + @AssemblyName + N'%'
ORDER BY asm.[name], afl.[file_id];

如果程序集是从 VARBINARY 文字/十六进制字节(即 0x4D5A9000...)加载的,则 [name]sys. assembly_files 中的 [name] 列应与 sys.assemblies 中的 [name] 列相同(这是 CREATE ASSEMBLY 语句)。


Querying the sys.assembly_files table, I notice that the record exists there but not on the left side

需要明确的是,问题中的两个屏幕截图都清楚地显示了一长串命名非常糟糕(并且明显以编程方式)的程序集。如果条目不存在于 sys.assemblies< 中,则无论如何都不可能在 sys.assemble_files(或任何其他与程序集相关的管理 View )中显示该条目。/.

另外:您确定您在对象资源管理器中深入查询的查询窗口中位于同一个数据库中吗?

they only provided me a database backup

程序集物理存在于执行 CREATE ASSEMBLY 的每个数据库中,并显示在 sys.assembliessys.asssembly_files 和一些文件中其他系统目录 View 。这是 SQLCLR 的众多好处之一:程序集不像现在已弃用的外部存储过程 API/功能(即 XP)那样位于数据库外部。

I know I have to sign it...

那么我假设您要将 SQL Server 2017 之前的数据库恢复到 SQL Server 2017 或更高版本。在这种情况下,您确实需要签署所有未签名的程序集,但是不需要需要导出它们才能执行此操作(由于 Microsoft 误解了该问题,这是一种极其常见的误解自己,因此提供了有关该主题的不正确的文档)。鉴于您可以就地签署程序集以克服新的“CLR 严格安全”问题,解决这个问题相当简单:

SQLCLR vs. SQL Server 2017, Part 4: “Trusted Assemblies” – The Disappointment (Msg 10314)

以下是步骤摘要:

  1. 使用CREATE CERTIFICATE ...在包含程序集的数据库中创建证书(使用密码)
  2. 使用 ADD SIGNATURE TO Assembly::[{ assembly_name}] ... 对程序集进行签名
  3. 将证书复制到[master](但不是私钥!)
  4. 从证书创建登录
  5. 向基于签名的登录授予 UNSAFE ASSEMBLY 权限
  6. 您仍然需要确保每个程序集都具有正确的 PERMISSION_SET 来完成其需要执行的操作

以下是该文章中的演示脚本,您可以复制并调整该脚本以满足您的需求:

Avoiding "Trusted Assemblies" - Demo (在 PasteBin 上)


有关使用 SQLCLR 的更多信息,请访问:SQLCLR Info

更新(来自 O.P.):

问题是程序集的名称为 ComputeHashFuncAssmembly,但路径包含 a798b6eb4255719355458f3749073dc1b,因此需要 ALTER ASSEMBLY 。这也是它在左侧不可见的原因,因为它位于 ComputeHashFuncAssmembly 下,而不是十六进制代码。

enter image description here

我导出了程序集,因为原始 DLL 没有提供给我,而我想要它。

这些是签署程序集的步骤

USE [yourDatabase];
GO

CREATE CERTIFICATE [AssemblyCertificate]
ENCRYPTION BY PASSWORD = 'aPasswordYouChoose'
WITH SUBJECT = 'Assembly Certificate';

ADD SIGNATURE TO Assembly::[ComputeHashFuncAssmembly]
    BY CERTIFICATE [AssemblyCertificate]
    WITH PASSWORD = 'aPasswordYouChoose';

ALTER ASSEMBLY ComputeHashFuncAssmembly
    WITH PERMISSION_SET = SAFE;

-- Copy the certificate to the master
BACKUP CERTIFICATE [AssemblyCertificate] TO FILE = 'C:\temp\certificate.cer';

USE [master];
GO

-- DROP certificate [AssemblyCertificate];
CREATE CERTIFICATE [AssemblyCertificate]
FROM FILE ='C:\temp\certificate.cer';

CREATE LOGIN [login_AssemblyCertificate]
FROM CERTIFICATE [AssemblyCertificate];

GRANT UNSAFE ASSEMBLY TO [login_AssemblyCertificate];

关于sql - 是否可以找到用于在 SQL SERVER CLR 中加载程序集的原始路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64029832/

相关文章:

mysql - 为什么我收到子查询错误

sql - 根据多个条件在另一个表中根据 SUM(values) 更新一个表

sql-server - SQL Server 非聚集索引

sql-server - SQL MERGE INTO - 如何删除然后插入匹配/现有数据?

sql-server - FileLoadException/Msg 10314 运行 CLR 存储过程时出错

sql-server - 从另一个存储过程调用 SQLCLR 过程并获得 2 个返回值?

linq - 如何在 SQL CLR 中添加 Linq 支持

php - 如果存在则关联

sql - 一个简单的 postgresql 查询的算法改进

sql-server - 将 2 行连接成一行