Как сопоставить типы UDT T-SQL и C # CLR? - PullRequest
0 голосов
/ 20 ноября 2018

Не уверен, что этот вопрос имеет смысл, но я новичок в CLR / UDT и только что закончил, следуя приведенному ниже примеру: https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-2017

То, чего я хочу достичь сейчас, очень похоже.Я попытался добавить в строковом параметре в обязательном порядке, но при добавлении объекта C #, где проблема начинается.

Это мой C # Main:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void HelloName(Person person, [param: SqlFacet(MaxSize=-1)]out string result)
{
    SqlContext.Pipe.Send("Hello world!" + Environment.NewLine);
    result = "Hello, " + person.firstName + " " + person.lastName;
}

А это класс C # Person:

    public class Person
    {
        public string firstName;
        public string lastName;
        public Person(string firstName, string lastName)
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }

Я могу успешно создать сборку, но этопроцедура, где я застреваю.Я хочу сделать что-то вроде:

CREATE PROCEDURE helloname
(
    @person (@firstname nchar(300), @lastname nchar(300))
    @result nchar(300) OUTPUT
 )
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName

Но после некоторого исследования, очевидно, лучший способ обойти объекты - через UDT.Я последовал еще одному примеру и создал таблицу Person и PersonType, как показано ниже в T-SQL:

CREATE TABLE Person  
(  
    FirstName nvarchar(50),  
    LastName nvarchar(50)  
)  
Go  

CREATE TYPE PersonType AS TABLE  
(  
    FirstName nvarchar(50),  
    LastName nvarchar(50)  
)  
Go  

Ошибка возникает здесь:

CREATE PROCEDURE helloname
(
    @personType PersonType,
    @result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName

При попытке выполнения выдается «ПРОЦЕДУРА СОЗДАНИЯ для «helloname» завершилась неудачно, поскольку типы T-SQL и CLR для параметра «@personType» не совпадают.должным образом?Дайте мне знать, если я пойду по этому поводу совершенно неправильно / если есть более простое решение.В идеале я буду передавать список с несколькими типами переменных внутри Person.Заранее спасибо.

1 Ответ

0 голосов
/ 21 ноября 2018

Я думаю, вы неправильно поняли концепцию пользовательских типов.Это не то же самое, что определяемые пользователем типы данных (сопоставление случайного имени с фактическим типом данных T-SQL) или определяемые пользователем типы таблиц (предопределенные схемы таблиц, используемые для создания табличных переменных, обычно используемых в качестве табличных параметров).

Попробуйте это для лучшего вступления: CLR Определяемые пользователем типы

Дайте мне знать, если я пойду по этому поводу совершенно неправильно / если естьболее простое решение.В идеале я буду передавать список с несколькими типами переменных внутри Person.

Если хранимая процедура должна была быть хранимой процедурой T-SQL, то лучший способ сделать это - использовать определяемый пользователем тип таблицы / TVP (т. Е. CREATE TYPE PersonType AS TABLE...).Но поскольку SQLCLR не принимает TVP, вы можете сделать следующее:

  • создать список сложных «объектов» в виде XML-документа, который легко анализируется в .NET.Используйте SqlXml в качестве типа входного параметра .NET.
  • создайте локальную временную таблицу (т.е. начиная с одного #), заполните ее, а затем прочитайте из нее в хранимой процедуре SQLCLR, используя Context Connection = true в качестве строки подключения.Я не уверен, при каких условиях этот вариант будет лучше / проще, чем простая передача XML-документа, но он все еще доступен.

Другие примечания:

  1. Вам не нужна param: часть атрибута SqlFacet.
  2. Используйте SqlString в качестве входящего типа данных вместо string.Получить строку .NET через свойство ParamName.Value.Проверьте, если NULL через ParamName.IsNull свойство.
  3. Параметры не могут быть выражены как комбинации параметров.Значение @person (@firstname nchar(300), @lastname nchar(300)) не является допустимым синтаксисом ни при каких условиях.

Для получения дополнительной информации о работе с SQLCLR в целом посетите: SQLCLR Info

...