" type"之间有什么区别?和"子类型"关键字?

时间:2018-04-23 09:53:33

标签: oracle plsql

在一些PL / SQL示例代码中,我注意到typesubtype关键字的两种用法,每次都声明一个自定义类型(类似于C中的typedef关键字,例子)。

在我看来,他们的用法是可以互换的:他们的差异是什么?

1 个答案:

答案 0 :(得分:4)

如果您尝试使用更具体的精度/比例(或将其约束为NOT NULL)声明一种基本数据类型,请执行以下操作:

DECLARE
  TYPE int IS NUMBER(38,0);
BEGIN
  NULL;
END;
/

然后它将无效并且您得到例外:

  

ORA-06550:第2行,第15栏:PLS-00103:遇到符号&#34; NUMBER&#34;当期望下列之一时:(数组新范围记录varray char_base number_base decimal date_base clob_base blob_base bfile_base table ref固定变化稀疏符号&#34;范围&#34;替换为&#34; NUMBER&#34;继续。< / p>

相反,您想使用SUBTYPE关键字:

DECLARE
  SUBTYPE int IS NUMBER(38,0);
  SUBTYPE intn IS NUMBER(38,0) NOT NULL;
BEGIN
  NULL;
END;
/

例如 - A previous question where an answer was to use a SUBTYPE to constrain the data to specific precision and scale.

还要考虑以下声明:

  1. TYPE intlist IS TABLE OF NUMBER(38,0);
    
  2. TYPE intlist IS TABLE OF NUMBER(38,0) NOT NULL;
    
  3. SUBTYPE integern IS NUMBER(38,0) NOT NULL;
    TYPE intlist IS TABLE OF integern;
    
  4. TYPE intlist IS TABLE OF NUMBER(38,0);
    SUBTYPE intlistn IS intlist NOT NULL;
    
  5. 对于(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并根据代码段(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;
    /