Implementar tipos definidos por el usuario

En este tema se describe cómo crear y quitar tipos definidos por el usuario CLR (Common Language Runtime) en SQL Server.

Crear tipos definidos por el usuario

Para crear un tipo definido por el usuario en SQL Server, debe realizar los siguientes pasos en el orden especificado:

  • Defina el tipo definido por el usuario como una clase o estructura en un lenguaje compatible con Microsoft .NET Framework. Para obtener más información acerca de cómo programar tipos para CLR, vea Ejemplos de programación de CLR. Para obtener información acerca de los ejemplos, vea Consideraciones para instalar ejemplos y bases de datos de ejemplo de SQL Server. A continuación, compile la clase o estructura para generar un ensamblado en .NET Framework mediante el compilador del lenguaje correspondiente.

  • Registre el ensamblado en SQL Server mediante la instrucción CREATE ASSEMBLY. Para obtener más información acerca de los ensamblados de SQL Server, vea Ensamblados (motor de base de datos).

  • Cree el tipo que hace referencia al ensamblado registrado.

Nota

La implementación de un proyecto de SQL Server en Microsoft Visual Studio registra un ensamblado en la base de datos especificada para el proyecto. La implementación del proyecto también crea tipos CLR definidos por el usuario en la base de datos para todas las definiciones de clase anotadas con el atributo SqlUserDefinedType. Para obtener más información, vea Implementar objetos de base de datos de CLR.

Nota

De manera predeterminada, la capacidad de SQL Server de ejecutar código CLR está establecida en OFF. Se pueden crear, modificar y quitar objetos de base de datos que hagan referencia a módulos de código administrado, pero estas referencias no se ejecutarán en SQL Server a menos que se habilite la opción clr enabled mediante sp_configure.

Para crear, modificar o quitar un ensamblado

Para crear un tipo definido por el usuario

Quitar tipos definidos por el usuario

Para quitar un tipo definido por el usuario

Nota

Los tipos definidos por el usuario no se pueden modificar una vez creados, ya que los cambios podrían invalidar datos de tablas o índices. Para modificar un tipo, debe quitarlo y después volver a crearlo o emitir una instrucción ALTER ASSEMBLY mediante la cláusula WITH UNCHECKED DATA.

No se puede quitar un tipo definido por el usuario hasta que se hayan quitado todas las referencias a dicho tipo. Entre dichas referencias figuran las siguientes:

  • Columnas definidas en el tipo.

  • Columnas calculadas y restricciones CHECK cuyas expresiones hacen referencia al tipo.

  • Vistas y funciones enlazadas a esquemas que presentan expresiones en sus definiciones que hacen referencia al tipo.

  • Parámetros de funciones y procedimientos almacenados.

Para encontrar columnas que dependen de un tipo definido por el usuario

En el ejemplo siguiente se recuperan metadatos de columnas definidas en un tipo definido por el usuario ComplexNumber.

SELECT * FROM sys.columns 
WHERE user_type_id = TYPE_ID('ComplexNumber');

En el ejemplo siguiente se recuperan metadatos limitados para usuarios con menos privilegios de columnas definidas en el tipo definido por el usuario ComplexNumber.

SELECT * FROM sys.column_type_usages 
WHERE user_type_id = TYPE_ID('ComplexNumber');

Encontrar expresiones de columnas calculadas, expresiones de restricciones CHECK y expresiones de módulo que dependan de un tipo definido por el usuario

En el ejemplo siguiente se recuperan los nombres de las columnas calculadas (y todas sus tablas) con dependencia del tipo definido por el usuario SimpleUdt.

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; 

En el ejemplo siguiente se recuperan los nombres de las restricciones CHECK (y los objetos sobre los que están definidas) que presentan dependencia del tipo definido por el usuario SimpleUdt.

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;

En el ejemplo siguiente se recuperan los nombres de los módulos cuyas definiciones hacen referencia al tipo definido por el usuario SimpleUdt.

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

Para encontrar parámetros que dependen de un tipo definido por el usuario

En el ejemplo siguiente se recuperan los nombres de los parámetros (y los objetos a los que pertenecen) definidos en el tipo definido por el usuario ComplexNumber.

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;

En el ejemplo siguiente se recuperan metadatos limitados para usuarios con menos privilegios de parámetros definidos en el tipo definido por el usuario ComplexNumber.

SELECT * FROM sys.parameter_type_usages 
WHERE user_type_id = TYPE_ID('ComplexNumber');