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約束不會繼承。
子類型轉換
不受約束的子類型是其所基于的類型的別名。子類型(不受約束)的任何類型變量都可以與基本類型的變量互換而無需轉換,反之亦然。
受約束子類型的變量可以與基本類型的變量互換而無需轉換,但基本類型的變量只能在符合子類型約束時與受約束的子類型互換。如果基于相同的子類型,則受約束子類型的變量可以隱式地轉換為另一個子類型,并且約束值在其所轉換的子類型值范圍內。