SQL Server не может найти мою функцию в моей DLL/сборке

Я создал библиотечный класс на C# с помощью этого кода, как вы можете видеть:

namespace ManagedCodeAndSQLServer
{
    public class BaseFunctionClass
    {
        public BaseFunctionClass()
        {
        }


        [SqlProcedure]
        public static void GetMessage(SqlString strName, out SqlString
        strMessge)
        {
            strMessge = "Welcome," + strName + ", " + "your code is getting executed under CLR !";

        }
    }
}

Я построил этот проект со свойством UNSAFE Permission Set и добавил DLL в SQL Server, используя этот код:

use master;
grant external access assembly to [sa];
use SampleCLR;
CREATE ASSEMBLY ManagedCodeAndSQLServer
AUTHORIZATION dbo
FROM 'd:\ManagedCodeAndSQLServer.dll'
WITH PERMISSION_SET = UNSAFE
GO

Он добавил сборку как часть моей базы данных.

Я хочу вызвать функцию, как вы можете видеть:

CREATE PROCEDURE usp_UseHelloDotNetAssembly
@name nvarchar(200),
@msg nvarchar(MAX)OUTPUT
AS EXTERNAL NAME ManagedCodeAndSQLServer.[ManagedCodeAndSQLServer.
BaseFunctionClass].GetMessage
GO

Но я получаю эту ошибку:

Сообщение 6505, уровень 16, состояние 2, процедура usp_UseHelloDotNetAssembly, строка 1
Не удалось найти тип «ManagedCodeAndSQLServer.
BaseFunctionClass» в сборке «ManagedCodeAndSQLServer».


person Ehsan Akbar    schedule 17.02.2017    source источник
comment
@BradleyUffner я добавил этот код. Достаточно ли этого? Используйте master; предоставить сборку внешнего доступа к [sa]; использовать SampleCLR;   -  person Ehsan Akbar    schedule 17.02.2017
comment
@BradleyUffner спасибо, дорогой друг   -  person Ehsan Akbar    schedule 17.02.2017
comment
Пожалуйста, не используйте UNSAFE, нет абсолютно никаких причин для того, чтобы этот код не был помечен как SAFE. Кроме того, вам никогда не нужно предоставлять разрешения для sa, так как этот логин всегда имеет все разрешения.   -  person Solomon Rutzky    schedule 17.02.2017
comment
@BradleyUffner да, я сделал это на основе этой статьи codeproject .com/Статьи/19954/   -  person Ehsan Akbar    schedule 17.02.2017
comment
Кроме того, пожалуйста, не устанавливайте для своей базы данных значение TRUSTWORTHY ON. Это ненужный риск для безопасности. Кроме того, это только на уровне БД, а не на уровне сервера.   -  person Solomon Rutzky    schedule 17.02.2017
comment
@srutzky я выполняю это: ALTER DATABASE TestingCLR SET TRUSTWORTHY Off GO, но та же ошибка   -  person Ehsan Akbar    schedule 17.02.2017
comment
Я собираюсь удалить свои комментарии, так как люди, которые знают о безопасности sql больше меня, говорят, что мои предложения представляют угрозу безопасности. Я не хочу никому давать плохой совет.   -  person Bradley Uffner    schedule 17.02.2017
comment
На первый взгляд код выглядит просто отлично. Обычно эта ошибка возникает, если вы либо не указываете имя пространства имен, либо класс не помечен как общедоступный. но вы сделали и то, и другое. Вы уверены, что это точный код, который был в той сборке?   -  person Solomon Rutzky    schedule 17.02.2017
comment
@srutzky я компилирую свой код без небезопасной функции и выполняю этот код, как вы сказали, но с той же ошибкой: CREATE ASSEMBLY ManagedCodeAndSQLServer AUTHORIZATION dbo FROM 'd:\ManagedCodeAndSQLServer.dll' GO change database testingclr set trustworthy off; GO CREATE PROCEDURE usp_UseHelloDotNetAssembly name nvarchar(200), msg nvarchar(MAX)OUTPUT AS EXTERNAL NAME ManagedCodeAndSQLServer.[ManagedCodeAndSQLServer. BaseFunctionClass].GetMessage GO   -  person Ehsan Akbar    schedule 17.02.2017
comment
@srutzky да, я уверен   -  person Ehsan Akbar    schedule 17.02.2017
comment
@srutzky, не могли бы вы взглянуть на это, я пытаюсь реализовать эту статью codeproject.com/Articles/19954/   -  person Ehsan Akbar    schedule 17.02.2017
comment
Просто к вашему сведению: для этих комментариев вы можете заключить код в одиночные обратные кавычки для лучшего formatting :). Кроме того, я только что просмотрел эту статью, и она ужасна. Его следует удалить из codeproject. Пожалуйста, забудьте, что вы когда-либо видели это. Если вы изучаете SQLCLR, см. серию статей, которые я пишу по этой теме в SQL Server Central: Stairway to SQLCLR (для ознакомления с их содержимым требуется бесплатная регистрация). Я пробую ваш код в своей системе. Дам тебе знать.   -  person Solomon Rutzky    schedule 17.02.2017
comment
@srutzky большое спасибо. я пытаюсь разработать свой код на основе вашей статьи :)   -  person Ehsan Akbar    schedule 17.02.2017
comment
Итак, я попробовал ваш код из простого копирования и вставки отсюда. Когда я выполнил T-SQL, я получил ту же ошибку. Затем я заметил, что когда я копировал и вставлял, он сохранял новую строку между именем пространства имен и именем класса, заключенными в квадратные скобки. Я удалил новую строку, чтобы она отображалась как [ManagedCodeAndSQLServer.BaseFunctionClass], и это сработало. Я предположил, что новая строка в вашем SQL и даже в сообщении об ошибке была из-за форматирования, выполненного здесь, на S.O. Но похоже, что это действительно есть в вашем коде. Удалите новую строку, и она должна работать. Если это так, я опубликую ответ на него.   -  person Solomon Rutzky    schedule 17.02.2017
comment
@srutzky спасибо, это работает :)   -  person Ehsan Akbar    schedule 17.02.2017


Ответы (1)


Проблема неуловима, и в онлайн-формате, таком как здесь, кажется, что это просто вопрос форматирования. Но проблема полностью найдена здесь, в квадратных скобках:

AS EXTERNAL NAME ManagedCodeAndSQLServer.[ManagedCodeAndSQLServer.
BaseFunctionClass].GetMessage

После ManagedCodeAndSQLServer. есть символ новой строки, которого там быть не должно. Это даже отражено в сообщении об ошибке:

Сообщение 6505, уровень 16, состояние 2, процедура usp_UseHelloDotNetAssembly, строка 1
Не удалось найти тип «ManagedCodeAndSQLServer.
BaseFunctionClass» в сборке «ManagedCodeAndSQLServer».

что снова похоже на перенос слов
;-), но это не так. Если новая строка удалена так, что T-SQL выглядит следующим образом:

AS EXTERNAL NAME ManagedCodeAndSQLServer.[ManagedCodeAndSQLServer.BaseFunctionClass].GetMessage;

тогда он будет работать нормально.

Некоторые дополнительные примечания:

  1. Нет необходимости когда-либо предоставлять sa что-либо. Любой член фиксированной роли сервера sysadmin уже имеет все разрешения.
  2. Нет необходимости, чтобы код, показанный в вопросе, был помечен как-то иначе, чем SAFE. Пожалуйста, не помечайте сборки как UNSAFE, если в этом нет крайней необходимости.
  3. Нет необходимости устанавливать для базы данных значение TRUSTWORTHY ON. Это угроза безопасности, и ее следует избегать, кроме случаев абсолютной необходимости.
  4. Если вы изучаете SQLCLR, см. серию статей, которые я пишу по этой теме в SQL Server Central: Stairway to SQLCLR (требуется бесплатная регистрация, чтобы прочитать их содержимое, но оно того стоит :-).
person Solomon Rutzky    schedule 17.02.2017