sql-server - 如何从 SQL Server 进程卸载 native DLL(使用 [DllImport()] 属性加载)?

标签 sql-server sqlclr

我创建了一个 SQLCLR 用户定义函数,它调用 native C++ DLL。

native C++ DLL 是我的,如果我想对其进行更改,我需要停止 sqlservr 进程来复制新的。在生产中这是 Not Acceptable 。

即使我删除使用该 DLL 的程序集,该文件仍在使用中。

如何覆盖 native DLL?

编辑

DLL方法声明:

[DllImport("Library64.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr GetTiming();

MS 似乎在第一次调用它时加载库,并且似乎在进程终止时卸载......:)

最佳答案

听起来“引用”是由应用程序域持有的。您可以尝试卸载应用程序域,这应该可以清除该问题(最好的猜测,因为我无法测试这一点)。您可以通过对数据库进行任何安全更改来做到这一点。作品如下:

ALTER DATABASE {db_name} SET TRUSTWORTHY ON (or OFF if already ON);
GO
ALTER DATABASE {db_name} SET TRUSTWORTHY OFF (or ON if already OFF);
GO

请记住,这将卸载该特定数据库中的所有 AppDomain。这通常不是问题,因为人们很少在单个数据库中拥有多个应用程序域(这需要程序集由不同的用户拥有,并且大多数人只使用 dbo )。


要查看存在哪些应用程序域以及加载了哪些程序集,请运行以下命令:

SELECT DB_NAME(dca.[db_id]) AS [DatabaseName], dca.*, '---' AS [---], dcla.*
FROM sys.dm_clr_appdomains dca
INNER JOIN sys.dm_clr_loaded_assemblies dcla
        ON  dca.appdomain_address = dcla.appdomain_address
WHERE dca.[db_id] <> 32767;

如果该查询没有返回任何内容,并且您仍然无法替换该外部 DLL,请尝试以下操作(这似乎有点多,但在尝试其他操作之前我们需要知道它是否有效):

sp_configure 'clr enabled', 0;
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
RECONFIGURE;

另外两个可以尝试的选项是:

  • 创建一个可通过 DLLImport 调用的包装 DLL。它会调用你的 Library64.dll

  • 最后的手段是通过另一个非托管调用强制删除非托管 DLL。您没有使用 LoadLibrary() 创建 DLL ,但您应该能够使用 GetModuleHandleExA() 获得对它的引用然后在调用 FreeLibrary() 时使用该句柄。以下博客文章对此进行了描述:PInvoke Library Load/Unload Behavior – Freeing Unmanaged Libraries似乎这是唯一成功的方法。请参阅@John's answer具体代码。

关于sql-server - 如何从 SQL Server 进程卸载 native DLL(使用 [DllImport()] 属性加载)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32290350/

相关文章:

sql-server - SqlDependency 与 SQLCLR 对 WebService 的调用

sql - 单行到多列和多行

c# - 从 SQLCLR 调用时,带有 Remove=true 的 WinSCP Session.PutFiles 获取 "Error deleting file System Error. Code: 5"但在 SSIS 脚本任务中工作

sql-server - 链接服务器的替代方案,具有相同的速度

SQL QUERY 选择特定老板手下的员工

c# - 如何在不升级到 MSDTC 的情况下在 SQLCLR 中使用 TransactionScope

c# - "cursor like"读取 CLR 过程/函数内部

sql - 在MSSQL Server中将nvarchar转换为数值

sql - 每特定时间选择一行

sql - TSQL CTE(公用表表达式)错误