实现用户定义类型

本主题说明如何在 SQL Server 中创建和删除公共语言运行时 (CLR) 用户定义类型。

创建用户定义类型

若要在 SQL Server 中创建用户定义类型,必须按顺序执行下列步骤:

  • 使用 Microsoft.NET Framework 支持的语言将用户定义类型定义为类或结构。 有关如何在 CLR 中编写类型的详细信息,请参阅 CLR 用户定义类型。 然后,编译类或结构以在 .NET Framework 中使用相应的语言编译器生成程序集。

  • 使用 CREATE ASSEMBLY 语句在 SQL Server 中注册程序集。 有关 SQL Server 中的程序集的详细信息,请参阅程序集(数据库引擎)

  • 创建引用注册程序集的类型。

注意注意

在 MicrosoftVisual Studio 中部署 SQL Server 项目时,将在为该项目指定的数据库中注册一个程序集。部署项目时还会在数据库中为使用 SqlUserDefinedType 属性批注的全部类定义创建 CLR 用户定义类型。 有关详细信息,请参阅部署 CLR 数据库对象

注意注意

默认情况下,SQL Server 执行 CLR 代码的功能设置为 OFF。 您可以创建、修改和删除引用托管代码模块的数据库对象,但是这些引用不会在 SQL Server 中执行,除非已使用 sp_configure 启用了 clr enabled 选项

创建、修改或删除程序集

创建用户定义类型

删除用户定义类型

删除用户定义类型

注意注意

用户定义类型在创建后不能被修改,因为修改可能会使表或索引中的数据无效。 若要修改类型,必须删除并重新创建该类型,或者使用 WITH UNCHECKED DATA 子句发出 ALTER ASSEMBLY 语句。

在删除所有对用户定义类型的引用之前,不能删除该类型。 这些引用可能包括:

  • 针对该类型定义的列。

  • 其表达式引用该类型的计算列和 CHECK 约束。

  • 其定义中具有引用该类型的表达式的绑定到架构的视图和函数。

  • 函数参数和存储过程参数。

查找依赖于用户定义类型的列

以下示例检索有关针对用户定义类型 ComplexNumber 定义的列的元数据。

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

以下示例为最少特权用户检索有关针对用户定义类型 ComplexNumber 定义的列的有限元数据。

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

查找依赖于用户定义类型的计算列表达式、CHECK 约束表达式和模块表达式

以下示例检索依赖于用户定义类型 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; 

以下示例检索依赖于用户定义类型 SimpleUdt 的 CHECK 约束(以及针对其定义约束的对象)的名称。

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;

下面的示例将检索其定义引用了用户定义类型 SimpleUdt 的模块的名称。

USE AdventureWorks;
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

查找依赖于用户定义类型的参数

以下示例检索针对用户定义类型 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;

以下示例为最少特权用户检索有关针对用户定义类型 ComplexNumber 定义的参数的有限元数据。

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