Как выполнить пользовательскую функцию SQLCLR, добавленную непосредственно в SSDT sqlproj, и устранить ошибку ссылки SQL71501

Я пытался найти ответ на этот простой вопрос, но до сих пор не мог понять.

Допустим, у меня есть MyDb.sqlproj с различным содержимым sql (sprocs, представления, триггер и т. д.).

Я добавил новый UDF через Add-> New item -> SQL CLR C#, User Defined Function.

Например:

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 я вызываю метод clr, используя ВНЕШНЕЕ ИМЯ:

CREATE PROCEDURE ClrMethod1
  RETURNS [int] WITH EXECUTE AS CALLER
AS EXTERNAL NAME [MyDb].[MyNamespace.MyClass].[Method1]

Кажется, я перепробовал все, чтобы скомпилировать последнюю строку. Он не может разрешить ссылку и получить:

SQL71501: функция: [имя моей функции sql] имеет неразрешенную ссылку на сборку [MyDb]

Пожалуйста, укажите мне правильный способ заставить его работать. Что я мог упустить?

Я использую VS2010 SP1 и последнюю версию SSDT.


person Paul    schedule 17.05.2012    source источник
comment
Я обновил свой пост после того, как понял, что ваш файл *.cs на самом деле находится внутри вашего проекта SSDT. Надеюсь, это поможет вам.   -  person AaronLS    schedule 22.05.2012
comment
На самом деле это круто, потому что я не осознавал, что проекты SSDT могут компилировать CS, пока не попробовал это сейчас. Я собирался встать на полную катушку и сказать, что проект SSDT не компилирует файлы CS! Вы даже можете посмотреть на вывод сборки и увидеть ... о, подождите, он на самом деле создает DLL, я открываю его в .net Reflector, и, конечно же, есть новая функция CLR: D Я не уверен, как переименование проекта может влияет на имя сборки. .NET Reflector можно использовать для проверки имени сборки сгенерированной DLL позже, если это необходимо (в папке Project/Obj/Debug/).   -  person AaronLS    schedule 22.05.2012
comment
Неважно, это находится в разделе «Свойства проекта» -> «SQLCLR» -> «Имя сборки».   -  person AaronLS    schedule 22.05.2012
comment
Да, это отличная функция sqlproj! SQLCLR теперь является частью проекта базы данных, что на самом деле так и есть.   -  person Paul    schedule 22.05.2012


Ответы (1)


Вы должны добавить скомпилированную DLL, содержащую код CLR, в качестве ссылки. Итак, в вашем проекте MyDb SSDT-> Ссылки (щелкните правой кнопкой мыши) -> Добавить ссылку, перейдите к DLL.

Возможно, вам сойдет с рук ссылка на проект вместо DLL, если у вас есть проект CLR (библиотека классов) в том же решении, но в моем случае я ссылаюсь на DLL (скомпилированную для отдельного решения).

Что касается формата строки AS EXTERNAL NAME:

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

Примечание. Для объектов CLR я удаляю пространства имен из своих классов/кода просто для упрощения, потому что этот шаг обычно наиболее проблематичен. Легко спутать AssmeblyName/DLL Name/Namespace. AssemblyName можно найти в проекте библиотеки классов CLR, открыв Свойства проекта->Приложение->"Имя сборки:". Я бы удалил из него все небуквенно-цифровые/пробелы, просто чтобы упростить имя и исключить это как проблему.

Итак, я бы попробовал это, и как только вы заработаете, если вам действительно нужны пространства имен, вы можете добавить пространство имен и выяснить оттуда синтаксис, и, по крайней мере, вы будете знать, что другие части верны.


Хорошо, понял, что у вас есть файл *.cs внутри того же проекта SSDT. поэтому в этом случае, если ваш код таков:

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]

Это компилируется для меня. Примечание. Опять же, пространство имен не использовалось. Когда я добавил новый элемент... в сгенерированном коде не было пространства имен.

person AaronLS    schedule 21.05.2012