Partilhar via


Requisitos de tipo definido pelo usuário (UDT)

Aplica-se a:SQL Server

Você deve tomar várias decisões de design importantes ao criar um tipo definido pelo usuário (UDT) a ser instalado no SQL Server. Para a maioria das UDTs, a criação da UDT como uma estrutura é recomendada, embora criá-la como uma classe também seja uma opção. A definição UDT deve estar em conformidade com as especificações para a criação de UDTs para que seja registrada no SQL Server.

Requisitos para a implementação de UDTs

Para executar no SQL Server, seu UDT deve implementar os seguintes requisitos na definição UDT:

A UDT deve especificar o Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute. O uso do System.SerializableAttribute é opcional, mas recomendado.

  • O UDT deve implementar a interface System.Data.SqlTypes.INullable na classe ou estrutura criando um static público (Shared no Visual Basic) Null método. O SQL Server reconhece nulos por padrão. Isso é necessário para que o código em execução no UDT seja capaz de reconhecer um valor nulo.

  • O UDT deve conter um método de Parse de static pública (ou Shared) que ofereça suporte à análise de, e um método de ToString público para conversão em uma representação de cadeia de caracteres do objeto.

  • Um UDT com um formato de serialização definido pelo usuário deve implementar a interface System.Data.IBinarySerialize e fornecer um Read e um método Write.

  • O UDT deve implementar System.Xml.Serialization.IXmlSerializable, ou todos os campos públicos e propriedades devem ser de tipos que são XML serializáveis ou decorados com o atributo XmlIgnore se a substituição da serialização padrão for necessária.

  • Deve haver apenas uma serialização de um objeto UDT. A validação falhará se as rotinas serializar ou desserializar reconhecerem mais de uma representação de um objeto específico.

  • SqlUserDefinedTypeAttribute.IsByteOrdered deve ser true para comparar dados em ordem de bytes. Se a interface IComparable não for implementada e SqlUserDefinedTypeAttribute.IsByteOrdered for false, as comparações de ordem de bytes falharão.

  • Um UDT definido em uma classe deve ter um construtor público que não aceita argumentos. Opcionalmente, você pode criar mais construtores de classe sobrecarregados.

  • O UDT deve expor elementos de dados como campos públicos ou procedimentos de propriedade.

  • Os nomes públicos não podem ter mais de 128 caracteres e devem estar em conformidade com as regras de nomenclatura do SQL Server para identificadores, conforme definido em Identificadores de banco de dados.

  • sql_variant colunas não podem conter instâncias de um UDT.

  • Os membros herdados não são acessíveis a partir do Transact-SQL porque o sistema de tipo do SQL Server não está ciente da hierarquia de herança entre UDTs. No entanto, você pode usar herança ao estruturar suas classes e pode chamar esses métodos na implementação de código gerenciado do tipo.

  • Os membros não podem ser sobrecarregados, exceto para o construtor de classe. Se você criar um método sobrecarregado, nenhum erro será gerado quando você registrar o assembly ou criar o tipo no SQL Server. A deteção do método sobrecarregado ocorre em tempo de execução, não quando o tipo é criado. Métodos sobrecarregados podem existir na classe, desde que nunca sejam invocados. Depois de invocar o método sobrecarregado, um erro é gerado.

  • Todos os membros static (ou Shared) devem ser declarados como constantes ou somente leitura. Os membros estáticos não podem ser mutáveis.

  • Se o campo SqlUserDefinedTypeAttribute.MaxByteSize estiver definido como -1, o UDT serializado poderá ser tão grande quanto o limite de tamanho do objeto grande (LOB) (atualmente 2 GB). O tamanho do UDT não pode exceder o valor especificado no campo MaxByteSized.

Observação

Embora não seja usado pelo servidor para realizar comparações, você pode, opcionalmente, implementar a interface System.IComparable, que expõe um único método, CompareTo. Isso é usado no lado do cliente em situações em que é desejável comparar ou ordenar com precisão os valores UDT.

Serialização nativa

Escolher os atributos de serialização corretos para sua UDT depende do tipo de UDT que você está tentando criar. O formato de serialização Native utiliza uma estrutura simples que permite que o SQL Server armazene uma representação nativa eficiente do UDT no disco. O formato Native é recomendado se o UDT for simples e contiver apenas campos dos seguintes tipos:

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

Os tipos de valor que são compostos de campos desses tipos são bons candidatos para Native formato, como struct em C# ou Structure como são conhecidos no Visual Basic .NET. Por exemplo, um UDT especificado com o formato de serialização Native pode conter um campo de outro UDT que também foi especificado com o formato Native. Se a definição UDT for mais complexa e contiver tipos de dados que não estejam na lista anterior, você deverá especificar o formato de serialização UserDefined.

O formato Native tem os seguintes requisitos:

  • O tipo não deve especificar um valor para Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize.

  • Todos os campos devem ser serializáveis.

  • O System.Runtime.InteropServices.StructLayoutAttribute deve ser especificado como StructLayout.LayoutKindSequential se o UDT for definido em uma classe e não em uma estrutura. Este atributo controla o layout físico dos campos de dados e é usado para forçar os membros a serem dispostos na ordem em que aparecem. O SQL Server usa esse atributo para determinar a ordem dos campos para UDTs com vários valores.

Para obter um exemplo de um UDT definido com Native serialização, consulte o Point UDT em Criar tipos definidos pelo usuário com ADO.NET.

Serialização UserDefined

A configuração de formato UserDefined para o atributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute dá ao desenvolvedor controle total sobre o formato binário. Ao especificar a propriedade Format atributo como UserDefined, você deve executar as seguintes ações em seu código:

  • Especifique a propriedade opcional IsByteOrdered atributo. O valor padrão é false.

  • Especifique a propriedade MaxByteSize do Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.

  • Escreva código para implementar métodos Read e Write para o UDT implementando a interface System.Data.Sql.IBinarySerialize.

Para obter um exemplo de um UDT definido com UserDefined serialização, consulte o UDT de moeda em Criar tipos definidos pelo usuário com ADO.NET.

Observação

Os campos UDT devem usar serialização nativa ou ser persistentes para serem indexados.

Atributos de serialização

Os atributos determinam como a serialização é usada para construir a representação de armazenamento de UDTs e para transmitir UDTs por valor para o cliente. É necessário especificar o Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute ao criar o UDT. O atributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute indica que a classe é uma UDT e especifica o armazenamento para a UDT. Opcionalmente, você pode especificar o atributo Serializable, embora o SQL Server não exija isso.

O Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute tem as seguintes propriedades.

Formato

Especifica o formato de serialização, que pode ser Native ou UserDefined, dependendo dos tipos de dados do UDT.

IsByteOrdered

Um valor Boolean que determina como o SQL Server executa comparações binárias no UDT.

IsFixedLength

Indica se todas as instâncias deste UDT têm o mesmo comprimento.

MaxByteSize

O tamanho máximo da instância, em bytes. Você deve especificar MaxByteSize com o formato de serialização UserDefined. Para um UDT com serialização definida pelo usuário especificada, MaxByteSize refere-se ao tamanho total do UDT em sua forma serializada, conforme definido pelo usuário. O valor de MaxByteSize deve estar no intervalo de 1 a 8000ou definido como -1 para indicar que o UDT é maior que 8.000 bytes (o tamanho total não pode exceder o tamanho máximo do LOB). Considere uma UDT com uma propriedade de uma cadeia de caracteres de 10 caracteres (System.Char). Quando o UDT é serializado usando um BinaryWriter, o tamanho total da cadeia de caracteres serializada é de 22 bytes: 2 bytes por caractere Unicode UTF-16, multiplicado pelo número máximo de caracteres, mais 2 bytes de controle de sobrecarga incorridos com a serialização de um fluxo binário. Portanto, ao determinar o valor de MaxByteSize, o tamanho total da UDT serializada deve ser considerado: o tamanho dos dados serializados na forma binária mais a sobrecarga incorrida pela serialização.

ValidationMethodName

O nome do método usado para validar instâncias do UDT.

Definir isbyteordered

Quando a propriedade Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered é definida como true, você está de fato garantindo que os dados binários serializados possam ser usados para ordenação semântica das informações. Assim, cada instância de um objeto UDT ordenado por bytes só pode ter uma representação serializada. Quando uma operação de comparação é executada no SQL Server nos bytes serializados, seus resultados devem ser os mesmos como se a mesma operação de comparação ocorresse no código gerenciado. Os seguintes recursos também são suportados quando IsByteOrdered está definido como true:

  • A capacidade de criar índices em colunas desse tipo.

  • A capacidade de criar chaves primárias e estrangeiras, bem como CHECK e UNIQUE restrições em colunas desse tipo.

  • A capacidade de usar Transact-SQL ORDER BY, GROUP BYe PARTITION BY cláusulas. Nesses casos, a representação binária do tipo é usada para determinar a ordem.

  • A capacidade de usar operadores de comparação em Transact-SQL instruções.

  • A capacidade de persistir colunas computadas desse tipo.

Os formatos de serialização Native e UserDefined suportam os seguintes operadores de comparação quando IsByteOrdered está definido como true:

  • Igual a (=)
  • Não igual a (!=)
  • Maior que (>)
  • Menos de (<)
  • Maior ou igual a (>=)
  • Inferior ou igual a (<=)

Implementar anulabilidade

Além de especificar os atributos para seus assemblies corretamente, sua classe também deve oferecer suporte à anulabilidade. As UDTs carregadas no SQL Server reconhecem nulos, mas para que a UDT reconheça um valor nulo, a classe deve implementar a interface INullable. Para obter mais informações e um exemplo de como implementar a anulabilidade em um UDT, consulte Criar tipos definidos pelo usuário com ADO.NET.

Conversões de cadeia de caracteres

Para dar suporte à conversão de cadeia de caracteres de e para o UDT, você deve fornecer um método Parse e um método ToString em sua classe. O método Parse permite que uma cadeia de caracteres seja convertida em UDT. Ele deve ser declarado como static (ou Shared no Visual Basic) e tomar um parâmetro do tipo System.Data.SqlTypes.SqlString. Para obter mais informações e um exemplo de como implementar os métodos Parse e ToString, consulte Criar tipos definidos pelo usuário com ADO.NET.

Serialização XML

As UDTs devem oferecer suporte à conversão de e para o tipo de dados xml em conformidade com o contrato de serialização XML. O namespace System.Xml.Serialization contém classes que são usadas para serializar objetos em documentos ou fluxos de formato XML. Você pode optar por implementar serialização de xml usando a interface IXmlSerializable, que fornece formatação personalizada para serialização e desserialização XML.

Além de executar conversões explícitas de UDT para xml, a serialização XML permite:

  • Use XQuery sobre valores de instâncias UDT após a conversão para o xml tipo de dados.

  • Use UDTs em consultas parametrizadas e métodos da Web com XML Web Services nativos no SQL Server.

  • Use UDTs para receber uma carga em massa de dados XML.

  • Serialize DataSets que contenham tabelas com colunas UDT.

UDTs não são serializados em consultas FOR XML. Para executar uma consulta FOR XML que exiba a serialização XML de UDTs, converta explicitamente cada coluna UDT para o tipo de dados xml na instrução . Você também pode converter explicitamente as colunas para varbinary, varcharou nvarchar.