Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a:SQL Server
È necessario prendere diverse decisioni di progettazione importanti durante la creazione di un tipo definito dall'utente (UDT) da installare in SQL Server. Benché nella maggior parte dei casi sia consigliabile creare il tipo definito dall'utente come struttura, la creazione come classe rappresenta un'altra opzione valida. Per poter essere registrata con SQL Server, la definizione del tipo definito dall'utente deve essere conforme alle specifiche per la creazione di tipi definiti dall'utente.
Requisiti per l'implementazione dei tipi definiti dall'utente
Per l'esecuzione in SQL Server, il tipo definito dall'utente deve implementare i requisiti seguenti nella definizione del tipo definito dall'utente:
Il tipo definito dall'utente deve specificare il Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
. L'uso del System.SerializableAttribute
è facoltativo, ma consigliato.
Il tipo definito dall'utente deve implementare l'interfaccia
System.Data.SqlTypes.INullable
nella classe o nella struttura creando unstatic
pubblico (Shared
in Visual Basic)Null
metodo. SQL Server è compatibile con i valori Null per impostazione predefinita. Questa condizione è necessaria affinché il codice in esecuzione nel tipo definito dall'utente sia in grado di riconoscere un valore Null.Il tipo definito dall'utente deve contenere un
static
pubblico (oShared
)Parse
metodo che supporta l'analisi da e un metodo pubblico diToString
per la conversione in una rappresentazione di stringa dell'oggetto.Un tipo definito dall'utente con un formato di serializzazione definito dall'utente deve implementare l'interfaccia
System.Data.IBinarySerialize
e fornire unRead
e un metodoWrite
.Il tipo definito dall'utente deve implementare
System.Xml.Serialization.IXmlSerializable
oppure tutti i campi e le proprietà pubblici devono essere di tipi serializzabili o decorati con l'attributoXmlIgnore
se è necessario eseguire l'override della serializzazione standard.È necessario che sia presente solo una serializzazione di un oggetto del tipo definito dall'utente. La convalida ha esito negativo se le routine di serializzazione e deserializzazione riconoscono più di una rappresentazione di un oggetto specifico.
SqlUserDefinedTypeAttribute.IsByteOrdered
deve esseretrue
per confrontare i dati in ordine di byte. Se l'interfacciaIComparable
non è implementata eSqlUserDefinedTypeAttribute.IsByteOrdered
èfalse
, i confronti degli ordini di byte hanno esito negativo.Un tipo definito dall'utente specificato in una classe deve disporre di un costruttore pubblico che non accetta argomenti. Facoltativamente, è possibile creare più costruttori di classi di overload.
Il tipo definito dall'utente deve esporre elementi dati come campi pubblici o routine di proprietà.
I nomi pubblici non possono contenere più di 128 caratteri e devono essere conformi alle regole di denominazione di SQL Server per gli identificatori definiti in identificatori di database.
sql_variant colonne non possono contenere istanze di un tipo definito dall'utente.
I membri ereditati non sono accessibili da Transact-SQL perché il sistema dei tipi di SQL Server non è a conoscenza della gerarchia di ereditarietà tra tipi definiti dall'utente. È tuttavia possibile utilizzare l'ereditarietà quando si strutturano le classi ed è possibile chiamare tali metodi nell'implementazione di codice gestito del tipo.
Non è possibile eseguire l'overload dei membri, ad eccezione del costruttore della classe. Se si crea un metodo di overload, non viene generato alcun errore quando si registra l'assembly o si crea il tipo in SQL Server. Il rilevamento del metodo di overload si verifica in fase di esecuzione e non durante la creazione del tipo. I metodi di overload possono esistere nella classe purché non vengano mai richiamati. Quando si richiama il metodo di overload, viene generato un errore.
Qualsiasi membro
static
(oShared
) deve essere dichiarato come costanti o di sola lettura. I membri statici non possono essere modificabili.Se il campo
SqlUserDefinedTypeAttribute.MaxByteSize
è impostato su-1
, il tipo definito dall'utente serializzato può essere grande quanto il limite di dimensioni LOB (Large Object) (attualmente 2 GB). Le dimensioni del tipo definito dall'utente non possono superare il valore specificato nel campoMaxByteSized
.
Nota
Anche se non viene usato dal server per eseguire confronti, è possibile implementare facoltativamente l'interfaccia System.IComparable
, che espone un singolo metodo, CompareTo
. Questa operazione viene usata sul lato client in situazioni in cui è consigliabile confrontare o ordinare con precisione i valori definiti dall'utente.
Serializzazione nativa
La scelta degli attributi di serializzazione corretti per il tipo definito dall'utente dipende dal tipo di tipo definito dall'utente che si sta tentando di creare. Il formato di serializzazione Native
usa una struttura semplice che consente a SQL Server di archiviare una rappresentazione nativa efficiente del tipo definito dall'utente su disco. Il formato Native
è consigliato se il tipo definito dall'utente è semplice e contiene solo campi dei tipi seguenti:
I tipi valore composti da campi di questi tipi sono candidati validi per Native
formato, ad esempio struct
in C#, o Structure
come sono noti in Visual Basic .NET. Ad esempio, un tipo definito dall'utente specificato con il formato di serializzazione Native
potrebbe contenere un campo di un altro tipo definito dall'utente specificato anche con il formato Native
. Se la definizione del tipo definito dall'utente è più complessa e contiene tipi di dati non presenti nell'elenco precedente, è necessario specificare invece il formato di serializzazione UserDefined
.
Il formato Native
presenta i requisiti seguenti:
Il tipo non deve specificare un valore per
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize
.Tutti i campi devono essere serializzabili.
Il
System.Runtime.InteropServices.StructLayoutAttribute
deve essere specificato comeStructLayout.LayoutKindSequential
se il tipo definito dall'utente è definito in una classe e non in una struttura. Questo attributo controlla il layout fisico dei campi dati e viene utilizzato per forzare la disposizione dei membri in base all'ordine in cui vengono visualizzati. SQL Server usa questo attributo per determinare l'ordine dei campi per i tipi definiti dall'utente con più valori.
Per un esempio di tipo definito dall'utente con Native
serializzazione, vedere Point
tipo definito dall'utente in Creare tipi definiti dall'utente con ADO.NET.
Serializzazione Definita dall'utente
L'impostazione del formato UserDefined
per l'attributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
fornisce allo sviluppatore il controllo completo sul formato binario. Quando si specifica la proprietà dell'attributo Format
come UserDefined
, è necessario eseguire le azioni seguenti nel codice:
Specificare la proprietà dell'attributo
IsByteOrdered
facoltativa. Il valore predefinito èfalse
.Specificare la proprietà
MaxByteSize
delMicrosoft.SqlServer.Server.SqlUserDefinedTypeAttribute
.Scrivere codice per implementare metodi
Read
eWrite
per il tipo definito dall'utente implementando l'interfacciaSystem.Data.Sql.IBinarySerialize
.
Per un esempio di tipo definito dall'utente definito con UserDefined
serializzazione, vedere Currency UDT in Creare tipi definiti dall'utente con ADO.NET.
Nota
Ai fini dell'indicizzazione, i campi con tipo definito dall'utente devono utilizzare la serializzazione nativa o essere resi persistenti.
Attributi di serializzazione
Gli attributi consentono di determinare la modalità di utilizzo della serializzazione per costruire la rappresentazione di archiviazione dei tipi definiti dall'utente e per trasmettere tali tipi al client in base al valore. È necessario specificare il Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
durante la creazione del tipo definito dall'utente. L'attributo Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
indica che la classe è un tipo definito dall'utente e specifica la risorsa di archiviazione per il tipo definito dall'utente. Facoltativamente, è possibile specificare l'attributo Serializable
, anche se SQL Server non richiede questa operazione.
Il Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
ha le proprietà seguenti.
Formato
Specifica il formato di serializzazione, che può essere Native
o UserDefined
, a seconda dei tipi di dati del tipo definito dall'utente.
IsByteOrdered
Valore Boolean
che determina il modo in cui SQL Server esegue confronti binari nel tipo definito dall'utente.
IsFixedLength
Indica se tutte le istanze del tipo definito dall'utente sono della stessa lunghezza.
MaxByteSize
Dimensioni massime, in byte, dell'istanza. È necessario specificare MaxByteSize
con il formato di serializzazione UserDefined
. Per un tipo definito dall'utente con serializzazione definita dall'utente specificato, MaxByteSize
fa riferimento alle dimensioni totali del tipo definito dall'utente nel formato serializzato definito dall'utente. Il valore di MaxByteSize
deve essere compreso nell'intervallo di 1
da 8000
o impostato su -1
per indicare che il tipo definito dall'utente è maggiore di 8.000 byte (le dimensioni totali non possono superare le dimensioni lob massime). Si consideri un tipo definito dall'utente con una proprietà di una stringa di 10 caratteri (System.Char
). Quando il tipo definito dall'utente viene serializzato utilizzando un oggetto BinaryWriter, le dimensioni totali della stringa serializzata sono pari a 22 byte per ciascun carattere Unicode UTF-16, moltiplicati per il numero massimo di caratteri, più 2 byte di controllo per l'overhead generato dalla serializzazione di un flusso binario. Pertanto, quando si determina il valore di MaxByteSize
, è necessario considerare le dimensioni totali del tipo definito dall'utente serializzato: le dimensioni dei dati serializzati in formato binario più l'overhead generato dalla serializzazione.
ValidationMethodName
Nome del metodo utilizzato per convalidare le istanze del tipo definito dall'utente.
Set isbyteordered
Quando la proprietà Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered
è impostata su true
, si garantisce che i dati binari serializzati possano essere usati per l'ordinamento semantico delle informazioni. In questo modo, ogni istanza di un oggetto del tipo definito dall'utente ordinato per byte può disporre di una sola rappresentazione serializzata. Quando un'operazione di confronto viene eseguita in SQL Server nei byte serializzati, i risultati devono essere uguali a se la stessa operazione di confronto è stata eseguita nel codice gestito. Le funzionalità seguenti sono supportate anche quando IsByteOrdered
è impostato su true
:
Capacità di creare indici nelle colonne di questo tipo.
Possibilità di creare chiavi primarie ed esterne, nonché di
CHECK
e vincoliUNIQUE
sulle colonne di questo tipo.Possibilità di usare Transact-SQL
ORDER BY
clausole ,GROUP BY
ePARTITION BY
. In questi casi, per determinare l'ordine viene utilizzata la rappresentazione binaria del tipo.Possibilità di usare gli operatori di confronto nelle istruzioni Transact-SQL.
Capacità di garantire la persistenza delle colonne calcolate di questo tipo.
Sia i formati di serializzazione Native
che di UserDefined
supportano gli operatori di confronto seguenti quando IsByteOrdered
è impostato su true
:
- Uguale a (
=
) - Diverso da (
!=
) - Maggiore di (
>
) - Meno di (
<
) - Maggiore o uguale a (
>=
) - Minore o uguale a (
<=
)
Implementare il supporto dei valori Null
Oltre a specificare correttamente gli attributi per gli assembly, la classe deve inoltre supportare i valori Null. I tipi definiti dall'utente caricati in SQL Server sono in grado di riconoscere i valori Null, ma affinché il tipo definito dall'utente riconosca un valore Null, la classe deve implementare l'interfaccia INullable
. Per altre informazioni e un esempio di come implementare i valori Nullbility in un tipo definito dall'utente, vedere Creare tipi definiti dall'utente con ADO.NET.
Conversioni di stringhe
Per supportare la conversione di stringhe da e verso il tipo definito dall'utente, è necessario fornire un metodo Parse
e un metodo ToString
nella classe. Il metodo Parse
consente la conversione di una stringa in un tipo definito dall'utente. Deve essere dichiarato come static
(o Shared
in Visual Basic) e accettare un parametro di tipo System.Data.SqlTypes.SqlString
. Per altre informazioni e un esempio di come implementare i metodi Parse
e ToString
, vedere Creare tipi definiti dall'utente con ADO.NET.
Serializzazione XML
I tipi definiti dall'utente devono supportare la conversione da e verso il tipo di dati xml conforme al contratto per la serializzazione XML. Lo spazio dei nomi System.Xml.Serialization
contiene classi utilizzate per serializzare gli oggetti in documenti o flussi in formato XML. È possibile scegliere di implementare xml serializzazione usando l'interfaccia IXmlSerializable
, che fornisce formattazione personalizzata per la serializzazione XML e la deserializzazione.
Oltre a eseguire conversioni esplicite da UDT a xml, la serializzazione XML consente di:
Usare XQuery sui valori delle istanze definite dall'utente dopo la conversione nel tipo di dati xml
. Usare tipi definiti dall'utente nelle query con parametri e nei metodi Web con Servizi Web XML nativi in SQL Server.
Utilizzare i tipi definiti dall'utente per ricevere un caricamento bulk di dati XML.
Serializzare set di dati che contengono tabelle con colonne del tipo definito dall'utente.
I tipi definiti dall'utente non vengono serializzati nelle query FOR XML. Per eseguire una query FOR XML che visualizza la serializzazione XML dei tipi definiti dall'utente, convertire in modo esplicito ogni colonna definita dall'utente nel tipo di dati xml nell'istruzione SELECT
. È anche possibile convertire in modo esplicito le colonne in varbinary, varchar o nvarchar.