|
用户定义的数据类型和数据类型转换
什么是用户定义的数据类型?
用户定义的类型(常常简称为 UDT)是根据其他 DB2 数据类型(比如 INTEGER 或 CHAR 数据类型)创建的数据类型。UDT 甚至可以基于其他 UDT。
UDT 用于建立变量的上下文。它们允许追踪如何在应用程序中使用对象。还可以定义不同数据类型和 UDT 之间的关系。
我们来考虑一个简单的示例。假设您有一个应用程序用来确定美国和加拿大的商店之间的最佳路线。为了实现这个功能,必须同时使用公制和英制度量的长度。您可能不知道表中存储的数据是以千米还是以英里为单位的。可以使用一个 UDT 创建一个 KM 类型,使用另一个 UDT 创建一个 MILES 类型。通过明确地使用这些类型,可以清楚地知道表中存储的是哪种度量方式的数据。还可以编写一个函数,用来自动地将 KM 和 MILES 类型的数据相加。 图 1. UDT:KM 与 MILES
创建 UDT
可以用 CREATE DISTINCT TYPE 语句创建 UDT。该语句的语法如下:
-CREATE DISTINCT TYPE--distinct-type-name--AS----------------->
--| source-data-type |--WITH COMPARISONS----------------------|
|
源数据类型可以是 DB2 所使用的任何标准数据类型,但是 XML 除外。
以下是一些示例:
CREATE DISTINCT TYPE km AS INTEGER WITH COMPARISONS
CREATE DISTINCT TYPE miles AS INTEGER WITH COMPARISONS
|
当成功地创建了 UDT 时,DB2 将自动生成标准比较操作符(=、<>、<、<=、> 和 >=)。
授权
创建 UDT 的授权 ID 所持有的特权必须至少包括下列特权之一:
SYSADM 或 DBADM 权力
- 数据库上的
IMPLICIT_SCHEMA 权力(如果不同类型的模式名不指向现有的模式)
- 模式上的
CREATEIN 特权(如果不同类型的模式名指向现有的模式)
使用 UDT
刚接触 DB2 的开发人员在首次使用 UDT 时常常会造成错误,这是因为 UDT 与常规数据类型交互的方式和彼此之间交互的方式不同。通常,DB2 会自动地进行数据类型的转换,从而允许执行算术或比较操作。但是对于 UDT 则不会如此。
强制类型转换
DB2 并不自动地对所有数据类型进行转换。如果数据类型属于同一数据类型组(如 图 2 所示),则转换会自动进行。如果它们不属于同一组,就会出现错误。 图 2. DB2 数据类型组
例如,以下代码片段在 DB2 中会失败:
empno = CHAR(6) {but the data is always numeric}
SQL String: SELECT (empno + 1) AS new_emp_no FROM employee
|
这个语句将失败,因为无法将整数 “1” 与字符数据相加,即使该数据是一个数字的字符串表示。
转换
想要使用不同的 UDT 或数据类型进行比较或执行算术操作,可以使用 CAST 指令将它们转换成同一数据类型。以下是其语法:
CAST--(--objectName--AS--target-data-type--)----|
|
以下是一个示例:
让我们再看几个示例。首先,创建两个不同的类型和一个使用它们的表:
CREATE DISTINCT TYPE km AS INTEGER WITH COMPARISONS;
CREATE DISTINCT TYPE miles AS INTEGER WITH COMPARISONS;
CREATE TABLE cityInfo (
cityName CHAR(20),
width_k KM NOT NULL,
width_m MILES NOT NULL
);
|
下面的 SQL 语句会成功执行,因为 WHERE 子句中进行比较的数据类型正确地转换为相同的数据类型。这个 SQL 语句将整数 “10” 转换成 KM 类型以便进行比较。
SELECT cityName
FROM cityInfo
WHERE width_k > km(10)
|
现在,让我们修改上面的语句来模拟一个常见的错误。下面的语句不会成功,因为 DB2 不知道如何比较 MILES 和 KM 数据类型:
SELECT cityName
FROM cityInfo
WHERE width_k > width_m
|
但是,下面的语句将成功执行,因为这两种数据类型都被转换成 INTEGER 类型。
SELECT cityName
FROM cityInfo
WHERE CAST(width_k AS INTEGER) > CAST(width_m AS INTEGER)
| |