Поделиться через


Требования к определяемого пользователем типа (UDT)

Область применения:SQL Server

При создании определяемого пользователем типа (UDT) необходимо принять несколько важных решений для установки в SQL Server. В большинстве случаев рекомендуется создавать определяемый пользователем тип как структуру, хотя можно создавать его и в виде класса. Определение определяемого пользователем типа должно соответствовать спецификациям для создания определяемых пользователем пользователей, чтобы он был зарегистрирован в SQL Server.

Требования к реализации определяемых пользователем типов

Для запуска в SQL Server UDT необходимо реализовать следующие требования в определении определяемого пользователем типа:

UDT должен указать Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute. Использование System.SerializableAttribute является необязательным, но рекомендуется.

  • UDT должен реализовать интерфейс System.Data.SqlTypes.INullable в классе или структуре путем создания общедоступного static (Shared в Visual Basic) Null метода. SQL Server по умолчанию учитывает значение NULL. Это необходимо, чтобы программный код, принадлежащий определяемому пользователем типу, умел распознавать значения NULL.

  • UDT должен содержать открытый метод static (или Shared) Parse, поддерживающий синтаксический анализ, и общедоступный метод ToString для преобразования в строковое представление объекта.

  • Определяемый пользователем формат сериализации должен реализовать интерфейс System.Data.IBinarySerialize и предоставить Read и метод Write.

  • UDT должен реализовать System.Xml.Serialization.IXmlSerializable, или все открытые поля и свойства должны быть типами, которые являются xml-сериализуемыми или украшены атрибутом XmlIgnore, если требуется переопределение стандартной сериализации.

  • У объекта определяемого пользователем типа может быть только одна сериализация. Если программы сериализации или десериализации обнаружат несколько различных представлений конкретного объекта, проверка закончится ошибкой.

  • SqlUserDefinedTypeAttribute.IsByteOrdered необходимо true для сравнения данных в порядке байтов. Если интерфейс IComparable не реализован и SqlUserDefinedTypeAttribute.IsByteOrderedfalse, сравнение порядка байтов завершается ошибкой.

  • Определяемый пользователем тип, заданный в виде класса, должен иметь общедоступный конструктор без аргументов. При необходимости можно создать более перегруженные конструкторы классов.

  • Определяемый пользователем тип должен предоставлять доступ к элементам данных как к общедоступным полям или процедурам свойств.

  • Общедоступные имена не могут превышать 128 символов и должны соответствовать правилам именования SQL Server для идентификаторов, определенных в идентификаторах базы данных.

  • sql_variant столбцы не могут содержать экземпляры определяемого пользователем типа.

  • Унаследованные члены недоступны из Transact-SQL, так как система типов SQL Server не знает иерархии наследования среди определяемых пользователем пользователей. Однако можно использовать наследование при определении структуры классов и можно вызывать такие методы в реализации этих типов с помощью управляемого кода.

  • Члены не могут быть перегружены, за исключением конструктора классов. Если вы создаете перегруженный метод, ошибка не возникает при регистрации сборки или создании типа в SQL Server. Определение наличия перегруженного метода происходит во время выполнения, а не при создании типа. Перегруженные методы могут существовать в классе до тех пор, пока они никогда не вызываются. При вызове перегруженного метода возникает ошибка.

  • Все элементы static (или Shared) должны быть объявлены как константы или только для чтения. Статические элементы не могут быть изменяемыми.

  • Если для поля SqlUserDefinedTypeAttribute.MaxByteSize задано значение -1, сериализованный определяемый пользователем объект может быть таким же большим, как ограничение размера большого объекта (LOB) (в настоящее время составляет 2 ГБ). Размер определяемого пользователем значения не может превышать значение, указанное в поле MaxByteSized.

Примечание.

Хотя он не используется сервером для сравнения, вы можете при необходимости реализовать интерфейс System.IComparable, который предоставляет один метод, CompareTo. Это используется на стороне клиента в ситуациях, в которых желательно точно сравнить или упорядочить значения UDT.

Собственная сериализация

Выбор правильных атрибутов сериализации для определяемого пользователем типа зависит от типа UDT, который вы пытаетесь создать. Формат сериализации Native использует простую структуру, которая позволяет SQL Server хранить эффективное собственное представление определяемого пользователем типа на диске. Рекомендуется использовать формат Native, если UDT прост и содержит только поля следующих типов:

bool, байтов, сбайт, короткие, ushort, int, uint, long , ulong, float, double, , , , , , , , ,

Типы значений, состоящие из полей этих типов, являются хорошими кандидатами для Native формата, например struct в C#, или Structure, так как они известны в Visual Basic .NET. Например, определяемый пользователем формат сериализации Native может содержать поле другого определяемого пользователем типа, которое также было указано в формате Native. Если определение определяемого пользователем типа является более сложным и содержит типы данных, не входящие в предыдущий список, вместо этого необходимо указать формат сериализации UserDefined.

Формат Native имеет следующие требования:

  • Тип не должен указывать значение для Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize.

  • Все поля должны быть сериализуемыми.

  • System.Runtime.InteropServices.StructLayoutAttribute необходимо указать как StructLayout.LayoutKindSequential, если UDT определен в классе, а не в структуре. Этот атрибут управляет физической компоновкой полей данных. Он заставляет члены структуры располагаться в памяти в том порядке, в каком они описаны. SQL Server использует этот атрибут для определения порядка полей для определяемых пользователем типов с несколькими значениями.

Пример определяемого пользователем типа с сериализацией см. в создании определяемых пользователем типов с помощью ADO.NET.

Сериализация UserDefined

Параметр формата UserDefined для атрибута Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute предоставляет разработчику полный контроль над двоичным форматом. При указании свойства атрибута Format в качестве UserDefinedнеобходимо выполнить следующие действия в коде:

  • Укажите необязательное свойство атрибута IsByteOrdered. Значение по умолчанию — false.

  • Укажите свойство MaxByteSizeMicrosoft.SqlServer.Server.SqlUserDefinedTypeAttribute.

  • Напишите код для реализации методов Read и Write для определяемого пользователем типа, реализуя интерфейс System.Data.Sql.IBinarySerialize.

Пример определяемого пользователем типа с UserDefined сериализации см. в разделе "UDT" в создании определяемых пользователем типов с ADO.NET.

Примечание.

Чтобы поля определяемого пользователем типа можно было использовать в индексе, они должны иметь собственную сериализацию или быть сохраняемыми.

Атрибуты сериализации

Атрибуты определяют, каким образом сериализация используется для создания хранимых представлений определяемых пользователем типов, а также для передачи таких типов клиенту по значению. Необходимо указать Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute при создании определяемого пользователем запроса. Атрибут Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute указывает, что класс является определяемой пользователем и указывает хранилище для определяемого пользователем домена. При необходимости можно указать атрибут Serializable, хотя SQL Server этого не требует.

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute имеет следующие свойства.

Формат

Задает формат сериализации, который может быть Native или UserDefinedв зависимости от типов данных определяемого пользователем типа.

IsByteOrdered

Значение Boolean, определяющее, как SQL Server выполняет двоичные сравнения в определяемом пользователем объекте.

IsFixedLength

Указывает, имеют ли все экземпляры данного определяемого пользователем типа одинаковую длину.

MaxByteSize

Максимальный размер экземпляра в байтах. Необходимо указать MaxByteSize с форматом сериализации UserDefined. Для определяемого пользователем типа UDT с заданной сериализацией MaxByteSize относится к общему размеру определяемой пользователем модели в сериализованной форме, определенной пользователем. Значение MaxByteSize должно находиться в диапазоне 1 до 8000или задать значение -1, чтобы указать, что определяемый пользователем размер превышает 8000 байт (общий размер не может превышать максимальный размер бизнес-объекта). Рассмотрим определяемый пользователем объект с свойством строки из 10 символов (System.Char). При сериализации определяемого пользователем типа с помощью BinaryWriter общий размер сериализованной строки составляет 22 байта: 2 байта на символ Юникода UTF-16, умноженный на максимальное количество символов, а также 2 контрольных байта затрат на сериализацию двоичного потока. Поэтому при определении значения MaxByteSizeнеобходимо учитывать общий размер сериализованного определяемого пользователем типа: размер данных, сериализованных в двоичной форме, а также накладные расходы, связанные с сериализацией.

ValidationMethodName

Имя метода, используемого для проверки экземпляров определяемого пользователем типа.

Set isbyteordered

Если для свойства Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered задано значение true, вы фактически гарантируете, что сериализованные двоичные данные можно использовать для семантического упорядочения информации. Таким образом, каждый экземпляр объекта побайтно упорядоченного определяемого пользователем типа может иметь лишь одно сериализованное представление. При выполнении операции сравнения в SQL Server на сериализованных байтах его результаты должны совпадать с тем же результатом, что и при выполнении той же операции сравнения в управляемом коде. Следующие функции также поддерживаются, если для IsByteOrdered задано значение true:

  • Создание индексов для столбцов этого типа.

  • Возможность создавать первичные и внешние ключи, а также CHECK и UNIQUE ограничения для столбцов этого типа.

  • Возможность использовать предложения Transact-SQL ORDER BY, GROUP BYи PARTITION BY. В этих случаях для определения порядка используется двоичное представление типа.

  • Возможность использовать операторы сравнения в инструкциях Transact-SQL.

  • Сохранение вычисляемых столбцов этого типа.

Форматы сериализации Native и UserDefined поддерживают следующие операторы сравнения, если для IsByteOrdered задано значение true:

  • Равно (=)
  • Не равно (!=)
  • Знак "больше" (>)
  • Меньше (<)
  • Больше или равно (>=)
  • Меньше или равно (<=)

Реализация nullability

Помимо задания нужных атрибутов для сборок, создаваемый класс должен также поддерживать допустимость значений NULL. Определяемые пользователем элементы, загруженные в SQL Server, имеют значение NULL, но для распознавания значения NULL класс должен реализовать интерфейс INullable. Дополнительные сведения и пример реализации nullability в определяемом пользователем объекте см. в статье Создание определяемых пользователем типов с помощью ADO.NET.

Преобразования строк

Чтобы поддерживать преобразование строк в UDT и из него, необходимо предоставить метод Parse и метод ToString в классе. Метод Parse позволяет преобразовать строку в определяемую пользователем строку. Он должен быть объявлен как static (или Shared в Visual Basic) и принимать параметр типа System.Data.SqlTypes.SqlString. Дополнительные сведения и пример реализации методов Parse и ToString см. в статье Создание пользовательских типов с помощью ADO.NET.

Сериализация XML

Определяемые пользователем элементы должны поддерживать преобразование в тип данных XML и из него путем соответствия контракту для сериализации XML. Пространство имен System.Xml.Serialization содержит классы, которые используются для сериализации объектов в xml-формате документов или потоков. Вы можете реализовать сериализацию xml с помощью интерфейса IXmlSerializable, который обеспечивает настраиваемое форматирование для сериализации и десериализации XML.

Помимо выполнения явных преобразований из UDT в XML, сериализация XML позволяет выполнять следующие действия:

  • Используйте XQuery для значений экземпляров UDT после преобразования в тип данных XML-.

  • Используйте определяемые пользователем элементы в параметризованных запросах и веб-методах с собственными веб-службами XML в SQL Server.

  • Использовать определяемые пользователем типы для получения массовой загрузки XML-данных.

  • Сериализовать объекты DataSets, содержащие таблицы со столбцами определяемого пользователем типа.

Определяемые пользователем элементы не сериализуются в запросах FOR XML. Чтобы выполнить XML-запрос FOR XML, который отображает сериализацию XML определяемых пользователем объектов, явно преобразуйте каждый столбец UDT в тип данных xml в инструкции SELECT. Можно также явно преобразовать столбцы в varbinary, varchar или nvarchar.