我一直在试图找到这个简单问题的答案-但到目前为止,还没有找到答案。
假设我有MyDb.sqlproj,具有各种sql内容(存储过程,视图,触发器等)。
我通过“添加”->“新项目”->“ SQL CLR C#”(用户定义的函数)添加了新的UDF。
例如:
namespace MyNameSpace { public class MyClass { [SqlFunction(DataAccess = DataAccessKind.Read)] //I use different attributes here, but it doesn't matter public static int Method1() { return 0; } } }
在MyDb.sqlproj属性中,“ SQLCLR”选项卡MyDb是程序集的名称和默认名称空间
在我的sql代码中,我使用 EXTERNAL NAME 调用clr方法:
CREATE PROCEDURE ClrMethod1 RETURNS [int] WITH EXECUTE AS CALLER AS EXTERNAL NAME [MyDb].[MyNamespace.MyClass].[Method1]
我似乎尽了一切努力来编译最后一行。它无法解析引用并获得:
SQL71501:函数:[我的sql函数的名称]有对程序集[MyDb]的未解析的引用
请指出正确的方法以使其正常工作。我可能会缺少什么?
我正在使用VS2010 SP1和最新版本的SSDT
您必须添加包含CLR代码的已编译DLL作为参考。因此,在您的MyDb SSDT项目->参考(右键单击)->添加参考下,浏览到DLL。
如果您在同一解决方案中有CLR(类库)项目,则可能可以引用该项目而不是DLL,但是在我的情况下,我引用的是DLL(为单独的解决方案编译)。
至于AS EXTERNAL NAME行的格式:
AS EXTERNAL NAME
AS EXTERNAL NAME [AssemblyName].[ClassName].[FunctionName]
注意: 对于CLR对象,为了简化起见,我从类/代码周围删除了名称空间,因为此步骤通常是最有问题的。容易混淆AssmeblyName / DLL名称/命名空间。通过访问“项目属性”->“应用程序”->“程序集名称:”,可以在CLR类库项目中找到AssemblyName。我会从中删除所有非字母数字/空格,只是为了简化名称并排除出现问题。
因此,我会尝试一下,一旦您能正常工作,如果您真的想要名称空间,则可以添加名称空间并从中找出语法,至少您知道其他部分是正确的。
确定,您实际上在同一个SSDT项目中有一个* .cs文件。所以在这种情况下,如果您的代码是这样的:
CS文件:
public partial class UserDefinedFunctions { [Microsoft.SqlServer.Server.SqlFunction] public static SqlString SqlFunction1() { // Put your code here return new SqlString (string.Empty); } }
SQL文件:
CREATE PROCEDURE ClrMethod1 RETURNS [int] WITH EXECUTE AS CALLER AS EXTERNAL NAME [MyDB].[UserDefinedFunctions].[SqlFunction1]
这为我编译。 注意: 再次没有使用名称空间。当我执行Add New Item …时,生成的代码没有命名空间。