“ type”和“ subtype”关键字有什么区别?

Fre*_*ios 2 oracle plsql

在某些PL / SQL示例代码中,我每次都使用typesubtype关键字来声明自定义类型(typedef例如,类似于C中的关键字)。

在我看来,它们的用法是可以互换的:它们有什么区别?

MT0*_*MT0 5

如果您尝试声明具有更具体的精度/小数位(或将其约束为NOT NULL)的基本数据类型,如下所示:

DECLARE
  TYPE int IS NUMBER(38,0);
BEGIN
  NULL;
END;
/
Run Code Online (Sandbox Code Playgroud)

然后它将无法正常工作,并且您得到异常:

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;
/
Run Code Online (Sandbox Code Playgroud)

例如- 先前的问题,答案是使用a SUBTYPE将数据约束为特定的精度和比例。


还请考虑以下声明:

  1. TYPE intlist IS TABLE OF NUMBER(38,0);
    
    Run Code Online (Sandbox Code Playgroud)
  2. TYPE intlist IS TABLE OF NUMBER(38,0) NOT NULL;
    
    Run Code Online (Sandbox Code Playgroud)
  3. SUBTYPE integern IS NUMBER(38,0) NOT NULL;
    TYPE intlist IS TABLE OF integern;
    
    Run Code Online (Sandbox Code Playgroud)
  4. TYPE intlist IS TABLE OF NUMBER(38,0);
    SUBTYPE intlistn IS intlist NOT NULL;
    
    Run Code Online (Sandbox Code Playgroud)

对于(1),列表可以是NULL并且列表的元素可以是NULL

DECLARE
  TYPE intlist IS TABLE OF NUMBER(38,0);
  list intlist := NULL;
BEGIN
  list := intlist( 1, 2, NULL, 4 );
END;
/
Run Code Online (Sandbox Code Playgroud)

(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;
/
Run Code Online (Sandbox Code Playgroud)

要强制列表不能为空,NULL您需要SUBTYPE按照intlistn代码片段(4)中的说明声明a 并对其施加约束。

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;
/
Run Code Online (Sandbox Code Playgroud)