我对在 SQL Server 中使用程序集 CLR 非常陌生
是否可以找到用于加载程序集的原始路径?
考虑到这是创建程序集的方式,我需要“来自”路径
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%'
此问题的解决方案也可能帮助您解决其中的任何问题
错误:
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.assemblies
、sys.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)
以下是步骤摘要:
- 使用
CREATE CERTIFICATE ...在包含程序集的数据库中创建证书(使用密码)
- 使用
ADD SIGNATURE TO Assembly::[{ assembly_name}] ... 对程序集进行签名
- 将证书复制到
[master]
(但不是私钥!) - 从证书创建登录
- 向基于签名的登录授予
UNSAFE ASSEMBLY
权限 - 您仍然需要确保每个程序集都具有正确的
PERMISSION_SET
来完成其需要执行的操作
以下是该文章中的演示脚本,您可以复制并调整该脚本以满足您的需求:
Avoiding "Trusted Assemblies" - Demo (在 PasteBin 上)
有关使用 SQLCLR 的更多信息,请访问:SQLCLR Info
更新(来自 O.P.):
问题是程序集的名称为 ComputeHashFuncAssmembly,但路径包含 a798b6eb4255719355458f3749073dc1b,因此需要 ALTER ASSEMBLY
。这也是它在左侧不可见的原因,因为它位于 ComputeHashFuncAssmembly 下,而不是十六进制代码。
我导出了程序集,因为原始 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/