Crear tipos definidos por el usuario: requisitos

Se aplica a:SQL Server

Debe tomar varias decisiones de diseño importantes al crear un tipo definido por el usuario (UDT) que se va a instalar en Microsoft SQL Server. Para la mayoría de los UDT, se recomienda la creación del UDT como una estructura, aunque también puede crearse como una clase. La definición udT debe cumplir las especificaciones para crear UDT para que se registre con SQL Server.

Requisitos para implementar un UDT

Para ejecutarse en SQL Server, el UDT debe implementar los siguientes requisitos en la definición de UDT:

El UDT debe especificar Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute. El uso de System.SerializableAttribute es opcional, pero se recomienda.

  • El UDT debe implementar la interfaz System.Data.SqlTypes.INullable en la clase o estructura mediante la creación de un método Nullestático público (compartido en Microsoft Visual Basic). SQL Server es compatible con valores NULL de forma predeterminada. Esto es necesario para que el código que se ejecuta en el UDT pueda reconocer un valor NULL.

  • El UDT debe contener un método público estático (o Compartido) Parse que admita el análisis de y un método ToString público para convertir en una representación de cadena del objeto.

  • Un UDT con un formato de serialización definido por el usuario debe implementar la interfaz System.Data.IBinarySerialize y proporcionar un método Read y Write .

  • El UDT debe implementar System.Xml. Serialization.IXmlSerializable, o todos los campos y propiedades públicos deben ser de tipos que sean serializables XML o decorados con el atributo XmlIgnore si se requiere la invalidación de la serialización estándar.

  • Solo debe haber una serialización de un objeto UDT. Se produce un error en la validación si las rutinas de serialización o deserialización reconocen más de una representación de un objeto determinado.

  • SqlUserDefinedTypeAttribute.IsByteOrdered debe ser true para comparar los datos en orden de bytes. Si la interfaz IComparable no se implementa y SqlUserDefinedTypeAttribute.IsByteOrdered es false, se producirá un error en las comparaciones de orden de bytes.

  • Un UDT definido en una clase debe tener un constructor público que no tome ningún argumento. Si lo desea, puede crear otros constructores de clase sobrecargados.

  • El UDT debe exponer elementos de datos como procedimientos de propiedad o campos públicos.

  • Los nombres públicos no pueden tener más de 128 caracteres y deben cumplir las reglas de nomenclatura de SQL Server para los identificadores definidos en Identificadores de base de datos.

  • sql_variant columnas no pueden contener instancias de un UDT.

  • Los miembros heredados no son accesibles desde Transact-SQL porque el sistema de tipos de SQL Server no es consciente de la jerarquía de herencia entre udT. Sin embargo, puede usar la herencia al estructurar sus clases y puede llamar a dichos métodos en la implementación del código administrado del tipo.

  • No es posible sobrecargar los miembros, salvo el constructor de clase. Si crea un método sobrecargado, no se genera ningún error al registrar el ensamblado o crear el tipo en SQL Server. La detección del método sobrecargado se produce en tiempo de ejecución, no cuando se crea el tipo. Puede haber métodos sobrecargados en la clase siempre y cuando no se invoquen nunca. Al invocar al método sobrecargado se produce un error.

  • Los miembros estáticos (o compartidos) deben declararse como constantes o como de solo lectura. Los miembros estáticos no pueden ser mutables.

  • Si el campo SqlUserDefinedTypeAttribute.MaxByteSize está establecido en -1, el UDT serializado puede ser tan grande como el límite de tamaño de objeto grande (LOB) (actualmente 2 GB). El tamaño del UDT no puede superar el valor especificado en el campo MaxByteSized .

Nota

Aunque el servidor no lo usa para realizar comparaciones, opcionalmente puede implementar la interfaz System.IComparable , que expone un único método, CompareTo. Se usa del lado cliente en situaciones en las que se desean realizar comparaciones precisas u ordenar los valores UDT.

Serialización nativa

La elección de los atributos de serialización correctos para su UDT depende del tipo de UDT que está intentando crear. El formato de serialización nativa utiliza una estructura muy sencilla que permite SQL Server almacenar una representación nativa eficaz del UDT en el disco. Se recomienda el formato nativo si el UDT es simple y solo contiene campos de los siguientes tipos:

bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, SqlByte, SqlInt16, SqlInt32, SqlInt64, SqlDateTime, SqlSingle, SqlDouble, SqlMoney, SqlBoolean

Los tipos de valor que se componen de campos de los tipos anteriores son buenos candidatos para el formato nativo , como estructuras en Visual C#, (o Estructuras como se conocen en Visual Basic). Por ejemplo, un UDT especificado con el formato de serialización nativo puede contener un campo de otro UDT que también se especificó con el formato nativo . Si la definición de UDT es más compleja y contiene tipos de datos que no están en la lista anterior, debe especificar el formato de serialización UserDefined en su lugar.

El formato nativo tiene los siguientes requisitos:

  • El tipo no debe especificar un valor para Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize.

  • Todos los campos deben ser serializables.

  • System.Runtime.InteropServices.StructLayoutAttribute debe especificarse como StructLayout.LayoutKindSequential si el UDT está definido en una clase y no en una estructura. Este atributo controla el diseño físico de los campos de datos y se usa para imponer a los miembros que se coloquen en el orden en que aparecen. SQL Server usa este atributo para determinar el orden de campo de los UDT con varios valores.

Para obtener un ejemplo de un UDT definido con serialización nativa , consulte el UDT de punto en codificación User-Defined tipos.

Serialización UserDefined

La configuración de formato UserDefined para el atributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute proporciona al desarrollador control total sobre el formato binario. Al especificar la propiedad de atributo Format como UserDefined, debe hacer lo siguiente en el código:

  • Especifique la propiedad de atributo IsByteOrdered opcional. El valor predeterminado es false.

  • Especifique la propiedad MaxByteSize de Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.

  • Escriba código para implementar métodos Read y Write para el UDT mediante la implementación de la interfaz System.Data.Sql.IBinarySerialize .

Para obtener un ejemplo de una UDT definida con serialización Definida por el usuario , consulte el UDT de moneda en Codificación User-Defined Tipos.

Nota

Los campos UDT deben usar la serialización nativa o conservarse para indizarse.

Atributos de serialización

Los atributos determinan el modo de usar la serialización para construir la representación de almacenamiento de los UDT y para transmitirlos por valor al cliente. Debe especificar Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute al crear el UDT. El atributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute indica que la clase es un UDT y especifica el almacenamiento para el UDT. Opcionalmente, puede especificar el atributo Serializable, aunque SQL Server no lo requiere.

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute tiene las siguientes propiedades.

Formato
Especifica el formato de serialización, que puede ser Nativo o UserDefined, en función de los tipos de datos del UDT.

IsByteOrdered
Valor booleano que determina cómo SQL Server realiza comparaciones binarias en el UDT.

IsFixedLength
Indica si todas las instancias de este UDT tienen la misma longitud.

MaxByteSize
Tamaño máximo de la instancia, expresado en bytes. Debe especificar MaxByteSize con el formato de serialización UserDefined . En el caso de un UDT con serialización definida por el usuario especificada, MaxByteSize hace referencia al tamaño total del UDT en su forma serializada según lo definido por el usuario. El valor de MaxByteSize debe estar en el intervalo de 1 a 8000 o establecido en -1 para indicar que el UDT es mayor que 8000 bytes (el tamaño total no puede superar el tamaño máximo de LOB). Considere un UDT con una propiedad de una cadena de 10 caracteres (System.Char). Cuando el UDT se serialice mediante BinaryWriter, el tamaño total de la cadena serializada será de 22 bytes: 2 bytes por carácter Unicode UTF-16, multiplicados por el número máximo de caracteres, más 2 bytes de control por la sobrecarga que se produce al serializar un flujo binario. Por lo tanto, al determinar el valor de MaxByteSize, se debe tener en cuenta el tamaño total del UDT serializado: el tamaño de los datos serializados en formato binario más la sobrecarga generada por la serialización.

ValidationMethodName
Nombre del método utilizado para validar las instancias del UDT.

Valor IsByteOrdered

Cuando la propiedad Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered está establecida en true, se garantiza que los datos binarios serializados se pueden usar para el orden semántico de la información. De esta forma, cada instancia de un objeto UDT ordenado por bytes solamente puede tener una representación serializada. Cuando se realiza una operación de comparación en SQL Server en los bytes serializados, sus resultados deben ser los mismos que si la misma operación de comparación se hubiera realizado en código administrado. Las siguientes características también se admiten cuando IsByteOrdered se establece en true:

  • Funcionalidad para crear los índices de las columnas de este tipo.

  • Funcionalidad para crear las claves principal y externa, así como las restricciones CHECK y UNIQUE en las columnas de este tipo.

  • La capacidad de usar cláusulas TRANSACT-SQL ORDER BY, GROUP BY y PARTITION BY. En estos casos, la representación binaria del tipo se usa para determinar el orden.

  • La capacidad de usar operadores de comparación en instrucciones Transact-SQL.

  • Funcionalidad para conservar las columnas calculadas de este tipo.

Tenga en cuenta que los formatos de serialización Native y UserDefined admiten los siguientes operadores de comparación cuando IsByteOrdered está establecido en true:

  • Igual a (=)

  • Distinto de (!=)

  • Mayor que (>)

  • Menor que (<)

  • Mayor o igual que (>=)

  • Menor o igual que (<=)

Implementar la nulabilidad

Además de especificar correctamente los atributos de los ensamblados, la clase también debe admitir la nulabilidad. Los UDT cargados en SQL Server reconocen valores NULL, pero para que el UDT reconozca un valor NULL, la clase debe implementar la interfaz INullable. Para obtener más información y un ejemplo de cómo implementar la nulabilidad en un UDT, consulte Codificación de tipos User-Defined.

Conversiones de cadenas

Para admitir la conversión de cadenas hacia y desde el UDT, debe proporcionar un método Parse y un método ToString en la clase . El método Parse permite convertir una cadena en un UDT. Debe declararse como estático (o Compartido en Visual Basic) y tomar un parámetro de tipo System.Data.SqlTypes.SqlString. Para obtener más información y un ejemplo de cómo implementar los métodos Parse y ToString , vea Codificación de tipos User-Defined.

Serialización XML

Los UDT deben admitir la conversión hacia y desde el tipo de datos xml conforme al contrato para la serialización XML. El System.Xml. El espacio de nombres de serialización contiene clases que se usan para serializar objetos en secuencias o documentos de formato XML. Puede optar por implementar la serialización xml mediante la interfaz IXmlSerializable , que proporciona formato personalizado para la serialización y deserialización XML.

Además de realizar conversiones explícitas de UDT a xml, la serialización XML permite:

  • Use Xquery sobre los valores de las instancias udT después de la conversión al tipo de datos xml .

  • Use udT en consultas con parámetros y métodos web con servicios web XML nativos en SQL Server.

  • Usar los UDT para recibir una carga masiva de datos XML.

  • Serializar conjuntos de datos que contengan tablas con columnas UDT.

Los UDT no se serializan en consultas FOR XML. Para ejecutar una consulta FOR XML que muestre la serialización XML de udT, convierta explícitamente cada columna UDT en el tipo de datos xml de la instrucción SELECT. También puede convertir explícitamente las columnas en varbinary, varchar o nvarchar.

Consulte también

Crear un tipo de User-Defined