【发布时间】:2017-06-20 23:54:45
【问题描述】:
我们正在移植一个 SQL Server 数据库,其中包括一个带有日期函数的 CLR 程序集(开发人员早已离开)。我从 DLL 创建了程序集(它在 sys.assemblies 中列出):
CREATE ASSEMBLY ArkaDB FROM 'C:\Temp\ArkaDB.dll' WITH PERMISSION_SET = SAFE;
但是当我尝试为 GetOIDate 函数创建 SQL 存储过程时:
create FUNCTION [dbo].[GetOIDate](@ActivityDate [datetime])
RETURNS [datetime] WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [ArkaDB].[ArkaDB.UserDefinedFunctions].[GetOIDate]
它给出错误“消息 6505,级别 16,状态 2,过程 GetOIDate,第 2 行 在程序集“ArkaDB”中找不到类型“ArkaDB.UserDefinedFunctions”。”
您可以在下面的 ILSpy 屏幕截图中看到 DLL 结构和函数代码。注意命名空间的破折号“-”。从this 的问题来看,我们应该在外部名称规范中包含一个命名空间。但是如果没有命名空间呢?答案here 表明您只需提供类似“EXTERNAL NAME [SqlClr].Math.[Add]”的类。我已经尝试了所有我能想到的变体,它们都给出了相同的找不到错误:
EXTERNAL NAME [ArkaDB].[ArkaDB.UserDefinedFunctions].[GetOIDate]
EXTERNAL NAME [ArkaDB].UserDefinedFunctions.[GetOIDate]
EXTERNAL NAME [ArkaDB].[.UserDefinedFunctions].[GetOIDate]
EXTERNAL NAME [ArkaDB].[-.UserDefinedFunctions].[GetOIDate]
EXTERNAL NAME [ArkaDB].[''.UserDefinedFunctions].[GetOIDate]
EXTERNAL NAME [ArkaDB].[ .UserDefinedFunctions].[GetOIDate]
有什么想法吗?我们正在运行 SQL Server 2012,而 DLL 最初是为 2008 R2 开发和安装的。 ILSpy for ArkaDB DLL
编辑:对于 srutzky,这里是 ILSpy UserDefinedFunctions class 中的公共类定义
【问题讨论】:
-
这个——
EXTERNAL NAME [ArkaDB].UserDefinedFunctions.[GetOIDate]——应该是正确的,或者你可以在类名周围加上方括号:EXTERNAL NAME [ArkaDB].[UserDefinedFunctions].[GetOIDate]。该类是否标记为“公共”? -
感谢您的回复。是的,该课程是公开的——请参见上面添加的图片。您对应该正确的格式是正确的。如果我在旧数据库中编写 SQL 函数创建脚本,它会生成“EXTERNAL NAME [ArkaDB].[UserDefinedFunctions].[GetOIDate]”。但是,当在新服务器中运行时,这会产生类似的错误“在程序集 'ArkaDB' 中找不到类型 'UserDefinedFunctions'”。我的下一步是尝试在 Visual Studio 中重建 DLL,但这对于遗留代码来说总是令人担忧:我有正确的源代码吗? VS版本有问题吗?
-
您的名字与 sys.assembl* 表中的名字匹配吗?如此处所述:docs.microsoft.com/en-us/sql/t-sql/statements/… 在页面上搜索
sys. -
这里只是猜测,但您可以尝试使用
DATETIME2而不是DATETIME作为输入参数和返回值类型吗? -
您是否 100% 确定您加载到 SQL Server 2012 中的 DLL 与用于加载 2008 R2 的 DLL 完全相同?您应该使用以下查询比较在
content列中找到的值:SELECT DATALENGTH([content]) AS [bytes], * FROM sys.assembly_files WHERE [name] LIKE N'%ArkaDB%' AND [file_id] = 1;。如果它们具有相同的字节数,那么您需要比较内容。您可以将两个服务器中的内容值复制并粘贴到查询中,在其中将它们创建为VARBINARY(MAX)或VARCHAR(MAX)变量,然后查看它们是否相等。
标签: sql-server dll .net-assembly sqlclr