Oracle 自訂類型

來源:互聯網
上載者:User

標籤:

一、子類型 
這種類型最簡單,類似類型的一個別名,主要是為了對常用的一些類型簡單化,它基於原始的某個類型。如: 
有些應用會經常用到一些貨幣類型:number(16,2)。如果在全域範圍各自訂這種類型,一旦需要修改該類型的精度,則需要一個個地修改。 
那如何?定義的全域化呢?於是就引出了子類型: 
subtype cc_num is number(16,2); 
這樣就很方便地解決了上述的麻煩。

 

我們可以在任何PL/SQL塊、子程式或包中定義自己的子類型

SUBTYPE  subtype_name IS  base_type[(constraint)] [NOT  NULL ]; 

subtype_name就是聲明的子類型的名稱,base_type可以是任何標量類型或使用者定義型別,約束只是用於限定基底類型的精度和數值範圍,或是最大長度。下面舉幾個例子:

DECLARE 
  SUBTYPE  birthdate IS  DATE  NOT  NULL ;   -- based on DATE type

  SUBTYPE  counter IS  NATURAL ;   -- based on NATURAL subtype

  TYPE  namelist IS  TABLE  OF  VARCHAR2 (10);

  SUBTYPE  dutyroster IS  namelist;   -- based on TABLE type

  TYPE  timerec IS  RECORD (
    minutes   INTEGER ,
    hours     INTEGER 
  );

  SUBTYPE  finishtime IS  timerec;   -- based on RECORD type

  SUBTYPE  id_num IS  emp.empno%TYPE ;   -- based on column type 

我們可以使用%TYPE或%ROWTYPE來指定基底類型。當%TYPE提供資料庫欄位中的資料類型時,子類型繼承欄位的大小約束(如果有的話)。但是,子類型並不能繼承其他約束,如NOT NULL。

2、使用子類型

一旦我們定義了子類型,我們就可以聲明該類型的變數、常量等。下例中,我們聲明了Counter類型變數,子類型的名稱代表了變數的使用目的:

DECLARE 
  SUBTYPE  counter IS  NATURAL ;

  ROWS   counter; 

下面的例子示範了如何約束使用者自訂子類型:

DECLARE 
  SUBTYPE  accumulator IS  NUMBER ;

  total   accumulator(7, 2); 

子類型還可以檢查數值是否越界來提高可靠性。下例中我們把子類型Numeral的範圍限制在-9到9之間。如果程式把這個範圍之外的數值賦給Numeral類型變數,那麼PL/SQL就會拋出一個異常。

DECLARE 
  SUBTYPE  numeral IS  NUMBER (1, 0);

  x_axis   numeral;   -- magnitude range is -9 .. 9 
  y_axis   numeral;
BEGIN 
  x_axis    := 10;   -- raises VALUE_ERROR 
  ...
END ; 

 

二、普通類型

create or replace type SH_type1 as object (
col1 number,
col2 varchar2(50),
col3 date,
);
create or replace type SH_TABLE_TYPE1 IS TABLE OF SH_type1;
create table t1_type of SH_type1;
insert into t1_type(COL1,COL2,COL3) values(SH_sqe_ASC.NEXTVAL,‘hello‘,sysdate-10);
SELECT * FROM T1_TYPE;

 

三、帶成員函數的類型體

這種類型包含了對類型中資料的內部處理,調用該類型時,可將處理後的資料返回給調用方。 
對上面的例子進行擴充。要求給當天加上特殊標識(【】)來反白。 
首先,在typ_calendar中增加一個成員函式宣告: 

create or replace type typ_calendar as object( 

年 varchar2(8),
月 varchar2(8),
星期日 varchar2(8),
星期一 varchar2(8),
星期二 varchar2(8),
星期三 varchar2(8),
星期四 varchar2(8),
星期五 varchar2(8),
星期六 varchar2(8),
本月最後一日 varchar2(2),

member function format(
curday date := sysdate,
fmtlen pls_integer := 8
)return typ_calendar
)

然後,建立一個type body,在type body中實現該成員函數: 

create or replace type body typ_calendar as
member function format(
curday date := sysdate,
fmtlen pls_integer := 8
) return typ_calendar as
v_return typ_calendar := typ_calendar(‘‘,‘‘,‘‘,‘‘,‘‘,‘‘,‘‘,‘‘,‘‘,‘‘);
v_dd varchar2(2) := to_char(curday, ‘dd‘);

function fmt(
fmtstr varchar2
)return varchar2 as
begin
return lpad(fmtstr, fmtlen, ‘ ‘);
end fmt;
begin
v_return.年 := 年;
v_return.月 := 月;
v_return.星期日 := fmt(星期日);
v_return.星期一 := fmt(星期一);
v_return.星期二 := fmt(星期二);
v_return.星期三 := fmt(星期三);
v_return.星期四 := fmt(星期四);
v_return.星期五 := fmt(星期五);
v_return.星期六 := fmt(星期六);
v_return.本月最後一日 := 本月最後一日;
if (年 || lpad(月, 2, ‘0‘) = to_char(curday, ‘yyyymm‘)) then
case v_dd
when 星期日 then
v_return.星期日 := fmt(‘【‘ || 星期日 || ‘】‘);
when 星期一 then
v_return.星期一 := fmt(‘【‘ || 星期一 || ‘】‘);
when 星期二 then
v_return.星期二 := fmt(‘【‘ || 星期二 || ‘】‘);
when 星期三 then
v_return.星期三 := fmt(‘【‘ || 星期三 || ‘】‘);
when 星期四 then
v_return.星期四 := fmt(‘【‘ || 星期四 || ‘】‘);
when 星期五 then
v_return.星期五 := fmt(‘【‘ || 星期五 || ‘】‘);
when 星期六 then
v_return.星期六 := fmt(‘【‘ || 星期六 || ‘】‘);
else null;
end case;
end if;

return v_return;
end format;
end;

插入測試資料: 

SQL> insert into tcalendar
2 select typ_calendar(‘2010‘,‘05‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘31‘) from dual
3 /
1 row inserted
SQL> insert into tcalendar
2 select typ_calendar(‘2010‘,‘05‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘31‘).format() from dual
3 /
1 row inserted
SQL> insert into tcalendar
2 select typ_calendar(‘2010‘,‘05‘,‘11‘,‘12‘,‘13‘,‘14‘,‘15‘,‘16‘,‘17‘,‘31‘).format() from dual
3 /
1 row inserted
SQL> select * from tcalendar;

 

可以看到資料已經置中處理了,並且到了第三條已經可以反白當前日期了。 
在這裡type 中的成員函數(member function)和靜態函數(static function)的區別有必要說明一下: 
成員函數有隱含參數self,即自身類型,可以在執行的時候引用當前的資料並對資料進行操作。它的調用可以如下:object_expression.method() 
靜態函數沒有該隱含參數。它的調用如下:type_name.method();

舉個例子: 
首先,建立一個帶靜態函式宣告的類型頭: 

 

Oracle 自訂類型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.