【发布时间】:2018-04-23 09:53:32
【问题描述】:
在一些 PL/SQL 示例代码中,我注意到 type 和 subtype 关键字的用法,每次都声明一个自定义类型(例如,类似于 C 中的 typedef 关键字)。
在我看来,它们的用法可以互换:它们有什么区别?
【问题讨论】:
在一些 PL/SQL 示例代码中,我注意到 type 和 subtype 关键字的用法,每次都声明一个自定义类型(例如,类似于 C 中的 typedef 关键字)。
在我看来,它们的用法可以互换:它们有什么区别?
【问题讨论】:
如果您尝试使用更具体的精度/比例(或将其限制为NOT NULL)声明一种基本数据类型,如下所示:
DECLARE
TYPE int IS NUMBER(38,0);
BEGIN
NULL;
END;
/
然后它不起作用,你得到异常:
ORA-06550:第 2 行,第 15 列:PLS-00103:在预期以下情况之一时遇到符号“NUMBER”: “范围”替换为“NUMBER”以继续。
相反,您想使用 SUBTYPE 关键字:
DECLARE
SUBTYPE int IS NUMBER(38,0);
SUBTYPE intn IS NUMBER(38,0) NOT NULL;
BEGIN
NULL;
END;
/
还要考虑以下声明:
TYPE intlist IS TABLE OF NUMBER(38,0);
TYPE intlist IS TABLE OF NUMBER(38,0) NOT NULL;
SUBTYPE integern IS NUMBER(38,0) NOT NULL;
TYPE intlist IS TABLE OF integern;
TYPE intlist IS TABLE OF NUMBER(38,0);
SUBTYPE intlistn IS intlist NOT NULL;
对于(1),列表可以是NULL,列表的元素可以是NULL:
DECLARE
TYPE intlist IS TABLE OF NUMBER(38,0);
list intlist := NULL;
BEGIN
list := intlist( 1, 2, NULL, 4 );
END;
/
(2) 和 (3) 是等效的 - 列表可以是 NULL,但列表中包含的任何元素都必须是 NOT NULL。
DECLARE
TYPE intlist IS TABLE OF NUMBER(38,0) NOT NULL;
-- This works:
list intlist := NULL;
BEGIN
-- This also works:
list := intlist( 1, 2, 3, 4 );
-- But this will raise an exception
-- list := intlist( 1, 2, NULL, 4 );
END;
/
要强制列表不能为NULL,您需要声明SUBTYPE 并根据sn-p (4) 中的intlistn 对其实施约束。
DECLARE
TYPE intlist IS TABLE OF NUMBER(38,0);
SUBTYPE intlistn IS intlist NOT NULL;
-- This works as the list is NOT NULL (even though an element of the list is)
list intlistn := intlist( 1, 2, NULL, 4 );
BEGIN
-- This does not works as the SUBTYPE constraint prevents it:
-- list := NULL;
END;
/
【讨论】: