1

我一直试图找到这个简单问题的答案——但到目前为止还没有弄清楚。

假设我有 MyDb.sqlproj,其中包含各种 sql 内容(存储过程、视图、触发器等)。

我通过 Add-> New item -> SQL CLR C#, User Defined Function 添加了一个新的 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 Properties 中,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

4

1 回答 1

2

您必须添加包含 CLR 代码的已编译 DLL 作为参考。因此,在您的 MyDb SSDT 项目->参考(右键单击)->添加参考下,浏览到 DLL。

如果您在同一个解决方案中有 CLR(类库)项目,您可能会通过引用项目而不是 DLL 而侥幸,但在我的情况下,我引用的是 DLL(为单独的解决方案编译)。

至于AS EXTERNAL NAME行的格式:

AS EXTERNAL NAME [AssemblyName].[ClassName].[FunctionName]

注意:对于 CLR 对象,我从类/代码周围删除命名空间只是为了简化事情,因为这一步通常是最有问题的。AssmeblyName/DLL Name/Namespace 很容易混淆。通过访问 Project Properties->Application->"Assembly Name:",可以在 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]

这为我编译。 注意:同样没有使用命名空间。当我添加新项目时...生成的代码没有命名空间。

于 2012-05-21T20:08:41.740 回答