如何使用 T-SQL 在 SQL Server 中创建用户定义的数据类型别名

发布于

除了 SQL Server 中可用的许多数据类型之外,您还可以选择创建自己的数据类型。其中一些被称为“用户定义的数据类型”,而另一些则被称为“别名数据类型”。

用户定义的数据类型通过 Microsoft.NET 框架公共语言运行库 (CLR) 中的程序集类实现。

别名数据类型基于 SQL Server 本机系统类型。换句话说,使用现有数据类型作为别名数据类型的基础。

话虽如此,我已经看到 Microsoft 在引用别名数据类型时使用术语“用户定义的数据类型别名”。我还看到它简称为“数据类型别名”。

无论采用哪种方式,本文都演示如何使用 Transact-SQL 创建用户定义的数据类型别名。

示例 1 – 创建别名数据类型

若要创建别名数据类型,请对要创建别名数据类型的数据库运行一条语句。CREATE TYPE

下面是基于 SQL Server varchar 数据类型创建用户定义的数据类型别名的代码示例:

USE Test;

CREATE TYPE clientcode
FROM varchar(8) NOT NULL;

输出:

Commands completed successfully.
Total execution time: 00:00:00.028

在本例中,我在名为 的数据库中创建名为 clientcode 的别名数据类型。Test

我的别名基于 varchar(8), 这意味着它可以是一个长度不超过 8 个字节的可变长度字符串。对于单字节编码字符集(如拉丁语),这将存储最多 8 个字符。但是,对于多字节编码字符集,字符数可能较少。

示例 2 – 查看别名数据类型

您可以使用 来检查别名数据类型的详细信息:sys.types

SELECT * FROM sys.types WHERE name = ‘clientcode’;

输出:

name              | clientcode
system_type_id    | 167
user_type_id      | 257
schema_id         | 1
principal_id      | NULL
max_length        | 8
precision         | 0
scale             | 0
collation_name    | SQL_Latin1_General_CP1_CI_AS
is_nullable       | 0
is_user_defined   | 1
is_assembly_type  | 0
default_object_id | 0
rule_object_id    | 0
is_table_type     | 0

我们可以看到此数据类型的标志是 ,这意味着它是用户定义的数据类型。is_user_defined1

在此示例中,我将结果缩小到仅数据类型。可以使用 返回有关数据库中所有数据类型的信息。有关详细信息,请参阅如何在 SQL Server 中返回数据类型列表。clientcodesys.types

现在已经创建了别名数据类型,我们可以继续使用它。

示例 3 – 创建使用别名的表

在此示例中,我创建了一个表,该表在其列定义之一中使用新创建的数据类型别名。

USE Test;

CREATE TABLE Client ( ClientCode clientcode PRIMARY KEY, FirstName varchar(50), LastName varchar(50) );

我们可以快速浏览一下表中的列:

SELECT c.name,
c.system_type_id, c.user_type_id, c.max_length, c.is_nullable FROM sys.columns c INNER JOIN sys.tables t ON t.object_id = c.object_id WHERE t.name = ‘Client’;

输出:

+------------+------------------+----------------+--------------+---------------+
| name       | system_type_id   | user_type_id   | max_length   | is_nullable   |
|------------+------------------+----------------+--------------+---------------|
| ClientCode | 167              | 257            | 8            | 0             |
| FirstName  | 167              | 167            | 50           | 1             |
| LastName   | 167              | 167            | 50           | 1             |
+------------+------------------+----------------+--------------+---------------+

还有更多的数据列,但我已将其缩小到与本文相关的一些列。

示例4 –插入数据

现在是时候将数据插入到使用用户定义的数据类型别名的列中了。

INSERT INTO Client VALUES (‘aaa00001’, ‘Satoshi’, ‘Nakamoto’);

现在选择该行:

SELECT * FROM Client;

输出:

+--------------+-------------+------------+
| ClientCode   | FirstName   | LastName   |
|--------------+-------------+------------|
| aaa00001     | Satoshi     | Nakamoto   |
+--------------+-------------+------------+

因此,我们可以看到我们的别名数据类型已接受指定的数据。

但除非我们试图打破它,否则这将不是一个适当的测试。

让我们尝试插入一个不符合我们的别名的值:

INSERT INTO Client VALUES (‘aaaa00002’, ‘Mikko’, ‘Linnamäki’);

输出:

Msg 8152, Level 16, State 30, Line 1
String or binary data would be truncated.

在这个示例中,我尝试插入一个需要 9 个字节才能存储的值,但别名最多只接受 8 个字节的值,因此它拒绝了它。

如果我删除其中一个字符,它可以正常工作:

INSERT INTO Client VALUES (‘aaa00002’, ‘Mikko’, ‘Linnamäki’);

SELECT * FROM Client;

输出:

+--------------+-------------+------------+
| ClientCode   | FirstName   | LastName   |
|--------------+-------------+------------|
| aaa00001     | Satoshi     | Nakamoto   |
| aaa00002     | Mikko       | Linnamäki  |
+--------------+-------------+------------+