PolarDB PostgreSQL版(兼容Oracle)支持用戶定義的PL/SQL子類型和(子類型)別名。子類型是具有一組可選約束的數據類型,這些約束限制可以存儲在該類型的列中的值。適用于該子類型所基于的類型的規則仍然適用,但您可以使用其他約束限制該類型中存儲值的精度或小數位數。

您可以在PL函數、存儲過程、匿名塊或包的聲明中定義子類型。語法如下:

SUBTYPE subtype_name IS type_name[(constraint)] [NOT NULL]

其中constraint為:

{precision [, scale]} | length

其中:

  • subtype_name:subtype_name指定子類型的名稱。
  • type_name:type_name指定子類型所基于的原始類型的名稱。

    type_name可能是:

    • PolarDB PostgreSQL版(兼容Oracle)支持的任何類型的名稱。
    • 任何復合類型的名稱。
    • 通過%TYPE運算符固定的列。
    • 另一種子類型的名稱。

包括constraint子句以定義支持精度或小數位數的類型的限制。

  • precision:precision指定子類型值中允許的總位數。
  • scale:scale指定子類型值中允許的小數位數。
  • length:length 指定CHARACTER、VARCHAR或TEXT基本類型值中允許的總長度。

包括NOTNULL子句以指定NULL值可不存儲在指定子類型的列中。

請注意,基于列的子類型將繼承列大小約束,但該子類型不會繼承NOT NULL或CHECK約束。

不受約束的子類型

要創建不受約束的子類型,請使用SUBTYPE命令指定新子類型名稱和該子類型所基于類型的名稱。例如,以下命令會創建一個名為address的子類型,該子類型具有類型CHAR的所有屬性:

SUBTYPE address IS CHAR;

您還可以創建另一個子類型的子類型(受約束或不受約束):

SUBTYPE cust_address IS address NOT NULL;

此命令創建名為cust_address的子類型,該子類型共享address子類型的所有屬性。包括NOT NULL子句以指定cust_address的值可能并非NULL。

受約束的子類型

基于字符類型創建子類型時包括length值以定義子類型的最大長度。例如:

SUBTYPE acct_name IS VARCHAR (15);

此示例基于VARCHAR數據類型創建名為acct_name的子類型,但限制為15個字符長度。

約束數字基本類型時,包括precision(指定子類型值中的最大位數)和可選的scale(指定小數點右側的位數)的值。例如:

SUBTYPE acct_balance IS NUMBER (5, 2);

此示例創建名為acct_balance的子類型,該子類型共享NUMBER類型的所有屬性,但小數點左側不得超過3位數,小數點右側不得超過2位數。

參數聲明(在函數或存儲過程標頭中)為形參。傳遞給函數或存儲過程的值為實參。調用函數或存儲過程時,調用方提供(0個或更多)實參。每個實參都分配給一個形參,該形參將值保存在函數或存儲過程的主體內。

如果將形參聲明為受約束的子類型:

  • 調用函數時,如果將實參分配給形參,則PolarDB PostgreSQL版(兼容Oracle)不會實施子類型約束。
  • 調用過程時,如果將實參分配給形參,則PolarDB PostgreSQL版(兼容Oracle)會實施子類型約束。

使用 %TYPE 運算符

您可以使用%TYPE表示法聲明固定到列的子類型。例如:

SUBTYPE emp_type IS emp.empno%TYPE

此命令創建名為emp_type的子類型,其基本類型匹配emp表中empno列的類型。基于列的子類型將共享列大小約束;NOT NULL和CHECK約束不會繼承。

子類型轉換

不受約束的子類型是其所基于的類型的別名。子類型(不受約束)的任何類型變量都可以與基本類型的變量互換而無需轉換,反之亦然。

受約束子類型的變量可以與基本類型的變量互換而無需轉換,但基本類型的變量只能在符合子類型約束時與受約束的子類型互換。如果基于相同的子類型,則受約束子類型的變量可以隱式地轉換為另一個子類型,并且約束值在其所轉換的子類型值范圍內。