Criar tipos definidos pelo usuário – Requisitos

Aplica-se a:SQL Server

Você deve tomar várias decisões de design importantes ao criar um UDT (tipo definido pelo usuário) para ser instalado no Microsoft SQL Server. De uma forma geral, é recomendável criar o UDT como uma estrutura, embora criá-lo como classe também seja uma opção. A definição de UDT deve estar em conformidade com as especificações para criar UDTs para que ela seja registrada com SQL Server.

Requisitos para implementação de UDTs

Para ser executado em SQL Server, o UDT deve implementar os seguintes requisitos na definição de UDT:

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

  • O UDT deve implementar a interface System.Data.SqlTypes.INullable na classe ou estrutura criando um método Nullestático público (Compartilhado no Microsoft Visual Basic). SQL Server tem reconhecimento nulo por padrão. Isso é necessário para que o código executado no UDT consiga reconhecer um valor nulo.

  • O UDT deve conter um método de análiseestático público (ou Compartilhado) que dê suporte à análise de e um método ToString público para converter 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 métodode Leitura e Gravação.

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

  • Deve haver apenas uma serialização de um objeto UDT. Haverá falha na validação se as rotinas de serialização ou desserialização reconhecerem mais de uma representação de um objeto específico.

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

  • Um UDT definido em uma classe deve ter um construtor público que não leve argumentos. Você tem a opção de criar construtores de classe sobrecarregados adicionais.

  • O UDT precisa 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 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 podem ser acessados do Transact-SQL porque o sistema de tipo SQL Server não está ciente da hierarquia de herança entre UDTs. Entretanto, você pode usar a herança ao estruturar suas classes, além de chamar esses métodos na implementação de código gerenciado do tipo.

  • Os membros não podem ficar sobrecarregados, com exceção do 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 detecção do método sobrecarregado ocorre em tempo de execução, e não quando o tipo é criado. Os métodos sobrecarregados podem existir na classe, contanto que nunca sejam invocados. Quando você invoca o método sobrecarregado, ocorre um erro.

  • Todos os membros estáticos (ou Compartilhados) devem ser declarados como constantes ou como somente leitura. 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 executar comparações, opcionalmente, você pode implementar a interface System.IComparable , que expõe um único método, CompareTo. Isso é usado no lado do cliente em situações nas quais é desejável comparar ou ordenar valores UDT com precisão.

Serialização nativa

A escolha dos atributos de serialização adequados para o UDT depende do tipo de UDT que você está tentando criar. O formato de serialização nativa utiliza uma estrutura muito simples que permite que SQL Server armazenem uma representação nativa eficiente do UDT no disco. O formato Nativo será 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 compostos por campos dos tipos acima são bons candidatos para o formato Nativo , como structs no Visual C#, (ou Estruturas como são conhecidos no Visual Basic). Por exemplo, um UDT especificado com o formato de serialização nativo pode conter um campo de outro UDT que também foi especificado com o formato Nativo . Se a definição de UDT for mais complexa e contiver tipos de dados que não estão na lista acima, você deverá especificar o formato de serialização UserDefined .

O formato Nativo tem os seguintes requisitos:

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

  • Todos os campos precisam 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. Esse atributo controla o layout físico dos campos de dados e é usado para obrigar os membros a ser dispostos na ordem em que aparecem. SQL Server usa esse atributo para determinar a ordem de campo para UDTs com vários valores.

Para obter um exemplo de um UDT definido com serialização nativa , consulte o UDT de Ponto em Tipos de User-Defined de Codificação.

Serialização UserDefined

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

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

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

  • Escreva código para implementar métodos de leitura e gravação para o UDT implementando a interface System.Data.Sql.IBinarySerialize.

Para obter um exemplo de um UDT definido com a serialização UserDefined, consulte o Conversor de Moedas UDT em Tipos de User-Defined de Codificação.

Observação

Os campos UDT precisam usar serialização nativa ou serem persistidos 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 transmiti-los por valor para o cliente. Você precisa especificar o Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute ao criar o UDT. O atributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute indica que a classe é um UDT e especifica o armazenamento para o UDT. Opcionalmente, você pode especificar o atributo Serializable, embora SQL Server não exija isso.

O Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute tem as propriedades a seguir.

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

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

IsFixedLength
Indica se todas as instâncias desse UDT têm a mesma extensão.

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 8.000 ou 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 um 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, multiplicados pelo número máximo de caracteres, mais 2 bytes de controle da sobrecarga ocasionada pela serialização de um fluxo binário. Portanto, ao determinar o valor de MaxByteSize, o tamanho total do UDT serializado deve ser considerado: o tamanho dos dados serializados no formato binário mais a sobrecarga incorrida pela serialização.

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

Definindo IsByteOrdered

Quando a propriedade Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered é definida como true, você garante 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 byte pode ter somente uma representação serializada. Quando uma operação de comparação é executada em SQL Server nos bytes serializados, seus resultados devem ser os mesmos que se a mesma operação de comparação tivesse ocorrido no código gerenciado. Os seguintes recursos também têm suporte quando IsByteOrdered é definido como true:

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

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

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

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

  • A capacidade de persistir colunas computadas desse tipo.

Observe que os formatos de serialização Native e UserDefined dão suporte aos seguintes operadores de comparação quando IsByteOrdered é definido como true:

  • Igual a (=).

  • Diferente de (!=)

  • Maior que (>)

  • Menor que (<)

  • Maior que ou igual a (>=)

  • Menor que ou igual a (<=)

Implementando a nulidade

Além de especificar corretamente os atributos dos assemblies, sua classe também precisa suportar a nulidade. UDTs carregados em SQL Server têm reconhecimento de nulo, mas para que o 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 nulidade em um UDT, consulte Codificando tipos de User-Defined.

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 um UDT. Ele deve ser declarado como estático (ou Compartilhado no Visual Basic) e usar 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 Codificando tipos de User-Defined.

Serialização XML

Os UDTs devem dar suporte à conversão de e para o tipo de dados xml em conformidade com o contrato para serialização XML. O System.Xml. O namespace de serialização contém classes que são usadas para serializar objetos em fluxos ou documentos no formato XML. Você pode optar por implementar a serialização 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 que você:

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

  • Use UDTs em consultas parametrizadas e métodos Web com serviços Web XML nativos em SQL Server.

  • Usar UDTs para receber um carregamento em massa de dados XML.

  • Serializar DataSets que contêm tabelas com colunas de UDT.

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

Consulte Também

Criando um tipo de User-Defined