Implementazione di tipi definiti dall'utente
In questo argomento viene descritto come creare ed eliminare tipi CLR (Common Language Runtime) definiti dall'utente in SQL Server.
Creazione di tipi definiti dall'utente
Per creare un tipo definito dall'utente in SQL Server, è necessario eseguire i passaggi seguenti nell'ordine in cui sono indicati:
Definire il tipo definito dall'utente come classe o struttura in un linguaggio Microsoft .NET Framework. Per ulteriori informazioni sulla programmazione di tipi in CLR, vedere Esempi di programmabilità CLR. Per informazioni sugli esempi, vedere Considerazioni per l'installazione di esempi e di database di esempio di SQL Server. Compilare quindi la classe o la struttura per compilare un assembly in .NET Framework utilizzando il compilatore appropriato.
Registrare l'assembly in SQL Server utilizzando l'istruzione CREATE ASSEMBLY. Per ulteriori informazioni sugli assembly in SQL Server, vedere Assembly (Motore di database).
Creare il tipo che fa riferimento all'assembly registrato.
Nota
Quando si distribuisce un progetto SQL Server in Microsoft Visual Studio, viene registrato un assembly nel database specificato per il progetto La distribuzione del progetto crea inoltre tipi CLR definiti dall'utente nel database per tutte le definizioni di classe annotate con l'attributo SqlUserDefinedType. Per ulteriori informazioni, vedere Distribuzione di oggetti di database CLR.
Nota
Per impostazione predefinita, in SQL Server non è possibile eseguire codice CLR. È possibile creare, modificare ed eliminare oggetti di database che fanno riferimento a moduli di codice gestito, ma tali riferimenti non verranno eseguiti in SQL Server a meno che non si attivi l'opzione clr enabled tramitesp_configure.
Per creare, modificare o eliminare un assembly
Per creare un tipo definito dall'utente
Eliminazione di tipi definiti dall'utente
Per eliminare un tipo definito dall'utente
Nota
Non è possibile modificare i tipi definiti dall'utente dopo averli creati, in quanto le modifiche potrebbero rendere non validi i dati di tabelle o indici. Per modificare un tipo, è necessario eliminarlo e quindi ricrearlo, oppure eseguire un'istruzione ALTER ASSEMBLY utilizzando la clausola WITH UNCHECKED DATA.
Non è possibile eliminare un tipo definito dall'utente finché non sono stati eliminati tutti i riferimenti a esso. Di seguito vengono descritti alcuni di questi riferimenti:
Colonne definite sul tipo.
Colonne calcolate e vincoli CHECK le cui espressioni fanno riferimento al tipo.
Funzioni e viste associate a schema con espressioni nelle relative definizioni che fanno riferimento al tipo.
Parametri di funzioni e stored procedure.
Per trovare le colonne che dipendono da un tipo definito dall'utente
Nell'esempio seguente vengono recuperati metadati relativi a colonne definite in un ComplexNumber di un tipo definito dall'utente.
SELECT * FROM sys.columns
WHERE user_type_id = TYPE_ID('ComplexNumber');
Nell'esempio seguente vengono recuperati metadati limitati per utenti con privilegi minimi relativi a colonne definite in un ComplexNumber di un tipo definito dall'utente.
SELECT * FROM sys.column_type_usages
WHERE user_type_id = TYPE_ID('ComplexNumber');
Per trovare espressioni di colonne calcolate, espressioni di vincolo CHECK ed espressioni di moduli che dipendono da un tipo definito dall'utente
Nell'esempio seguente vengono recuperati i nomi di colonne calcolate, con relative tabelle, che presentano una dipendenza da un SimpleUdt di un tipo definito dall'utente.
SELECT OBJECT_SCHEMA_NAME (referencing_id) AS referencing_schema_name,
OBJECT_NAME(referencing_id) AS referencing_name,
COL_NAME(referencing_id, referencing_minor_id) AS column_name,
is_caller_dependent,
is_ambiguous
FROM sys.sql_expression_dependencies
WHERE referenced_id = TYPE_ID('SimpleUdt')
AND referenced_class = 6
AND OBJECTPROPERTY(referencing_id, 'IsTable')=1;
Nell'esempio seguente vengono recuperati i nomi dei vincoli CHECK, con gli oggetti in cui sono definiti, che presentano una dipendenza da un SimpleUdt di un tipo definito dall'utente.
SELECT SCHEMA_NAME(o.schema_id) AS schema_name,
OBJECT_NAME(o.parent_object_id) AS table_name,
OBJECT_NAME(o.object_id) AS constraint_name
FROM sys.sql_expression_dependencies AS d
JOIN sys.objects AS o
ON o.object_id = d.referencing_id
WHERE referenced_id = TYPE_ID('SimpleUdt')
AND referenced_class = 6
AND OBJECTPROPERTY(o.object_id, 'IsCheckCnst')=1;
Nell'esempio seguente vengono recuperati i nomi dei moduli le cui definizioni fanno riferimento a un SimpleUdt di un tipo definito dall'utente.
USE AdventureWorks2008R2;
GO
SELECT referencing_schema_name, referencing_entity_name, referencing_id, referencing_class_desc, is_caller_dependent
FROM sys.dm_sql_referencing_entities ('SimpleUdt', 'TYPE');
GO
Per trovare i parametri che dipendono da un tipo definito dall'utente
Nell'esempio seguente vengono recuperati i nomi dei parametri, con gli oggetti a cui appartengono, definiti in un ComplexNumber di un tipo definito dall'utente.
SELECT OBJECT_NAME(object_id) AS object_name,
NULL AS procedure_number,
name AS param_name,
parameter_id AS param_num,
TYPE_NAME(p.user_type_id) AS type_name
FROM sys.parameters AS p
WHERE p.user_type_id = TYPE_ID('ComplexNumber')
ORDER BY object_name, procedure_number, param_num;
Nell'esempio seguente vengono recuperati i metadati limitati per utenti con privilegi minimi relativi a parametri definiti in un ComplexNumber di un tipo definito dall'utente.
SELECT * FROM sys.parameter_type_usages
WHERE user_type_id = TYPE_ID('ComplexNumber');