※物件
CREATE TYPE xxx_object AS OBJECT ( p1 varchar2(7), p2 number ); -------------------- DECLARE p xxx_object := xxx_object('default', 0); BEGIN p.p1 := 'ppp'; DBMS_OUTPUT.PUT_LINE(p.p1); DBMS_OUTPUT.PUT_LINE(p.p2); END;
※物件裡放什麼類型都可以
※陣列
陣列就是定義一組相同的類型,如字串陣列(裡面都是字串)、數字陣列(裡面都是數字)
※宣告陣列
DECLARE TYPE xxx_arrays IS TABLE OF VARCHAR(5) INDEX BY PLS_INTEGER; xxx xxx_arrays; BEGIN xxx(-5) := 'a'; xxx(0) := 'b'; xxx(3) := 'c'; DBMS_OUTPUT.PUT_LINE('xxx(-5)=' || xxx(-5)); DBMS_OUTPUT.PUT_LINE('xxx(0)=' || xxx(0)); DBMS_OUTPUT.PUT_LINE('xxx(3)=' || xxx(3)); --ORA-01403: no data found --DBMS_OUTPUT.PUT_LINE('xxx(4)=' || xxx(4)); END;
※TABLE OF後面接類型,而INDEX BY後面接的是索引裡面的類型,要用數字不能用NUMBER(TABLE OF後還是可寫NUMBER),只能用PLS_INTEGER;而字串就寫STRING,官網的5-1表有寫
※如果沒有給index,又想印出來會出錯
※陣列預設值
DECLARE TYPE xxx_arrays IS TABLE OF VARCHAR(5); xxx xxx_arrays := xxx_arrays('a','b','c'); BEGIN -- DBMS_OUTPUT.PUT_LINE('xxx(1)=' || xxx(1)); -- DBMS_OUTPUT.PUT_LINE('xxx(2)=' || xxx(2)); -- DBMS_OUTPUT.PUT_LINE('xxx(3)=' || xxx(3)); FOR i IN xxx.FIRST..xxx.LAST LOOP DBMS_OUTPUT.PUT_LINE('xxx(' || i || ')=' || xxx(i)); END LOOP; END;
※不能寫「INDEX BY XXX」,預設是從1開始跑,所以可以跑迴圈
※EXISTS
DECLARE TYPE xxx_arrays IS TABLE OF VARCHAR(5) INDEX BY PLS_INTEGER; xxx xxx_arrays; BEGIN xxx(0) := 'a'; xxx(1) := 'b'; xxx(2) := 'c'; FOR XXX IN 0..2 LOOP DBMS_OUTPUT.PUT_LINE(xxx); END LOOP; IF xxx.EXISTS(1) THEN DBMS_OUTPUT.PUT_LINE('存在=' || xxx(1)); ELSE DBMS_OUTPUT.PUT_LINE('不存在!'); END IF; FOR i IN 0..xxx.COUNT LOOP IF xxx.EXISTS(i) THEN DBMS_OUTPUT.PUT_LINE(xxx(i)); END IF; END LOOP; LOOP EXIT WHEN NOT xxx.EXISTS(i); DBMS_OUTPUT.PUT_LINE(xxx(i)); i := i + 1; END LOOP; WHILE xxx.EXISTS(i) LOOP DBMS_OUTPUT.PUT_LINE(xxx(i)); i := i + 1; END LOOP; END;
※結果:
0
1
2
存在!b
※使用FOR迴圈取出內容時,要配合EXITS,否則會報「ORA-01403:找不到資料」的錯
※其他方法可在官網找到
※%ROWTYPE
DECLARE TYPE xxx_arrays IS TABLE OF DEPT%ROWTYPE INDEX BY VARCHAR2(5); xxx xxx_arrays; BEGIN xxx('dept').dname := 'a'; xxx('dept').loc := 'b'; IF xxx.EXISTS('dept') THEN DBMS_OUTPUT.PUT_LINE('xxx(''dept'').dname=' || xxx('dept').dname); DBMS_OUTPUT.PUT_LINE('xxx(''dept'').loc=' || xxx('dept').loc); DBMS_OUTPUT.PUT_LINE('xxx(''dept'').deptno=' || xxx('dept').deptno); END IF; END;
※結果:
xxx('dept').dname=a
xxx('dept').loc=b
xxx('dept').deptno=
※陣列裡可以是個%ROWTYPE,如果沒給值印出,不會報錯,是空的
※配合記錄類型一起使用
DECLARE TYPE aaa is record ( x dept.deptno%type, y dept.dname%type, z dept.loc%type ); TYPE xxx_arrays IS TABLE OF aaa INDEX BY PLS_INTEGER; xxx xxx_arrays; BEGIN xxx(0).y := 'aaa'; xxx(0).z := 'bbb'; IF xxx.EXISTS(0) THEN DBMS_OUTPUT.PUT_LINE('xxx(0).y=' || xxx(0).y); DBMS_OUTPUT.PUT_LINE('xxx(0).z=' || xxx(0).z); DBMS_OUTPUT.PUT_LINE('xxx(0).x=' || xxx(0).x); END IF; END;
※結果:
xxx(0).y=aaa
xxx(0).z=bbb
xxx(0).x=
※記錄類型必須先宣告,不然陣列抓不到
※配合物件使用
CREATE TYPE xxx_object AS OBJECT ( p1 varchar2(7), p2 number ); -------------------- DECLARE p xxx_object := xxx_object('default', 0); TYPE arrs IS TABLE OF xxx_object INDEX BY PLS_INTEGER; arr arrs; BEGIN p.p1 := 'ppp'; DBMS_OUTPUT.PUT_LINE(p.p1); DBMS_OUTPUT.PUT_LINE(p.p2); arr(0) := p; FOR i IN arr.first..arr.last LOOP DBMS_OUTPUT.PUT_LINE(arr(i).p1); DBMS_OUTPUT.PUT_LINE(arr(i).p2); END LOOP; END;
※
※刪除
declare TYPE xxx_arrays IS TABLE OF VARCHAR(5); xxx xxx_arrays := xxx_arrays('a','b','b','c'); begin DBMS_OUTPUT.PUT_LINE('xxx=' || xxx.count); FOR i IN xxx.FIRST..xxx.LAST LOOP IF xxx(i) = 'b' THEN DBMS_OUTPUT.PUT_LINE('i=' || i); xxx.delete(i); END IF; END LOOP; DBMS_OUTPUT.PUT_LINE('xxx=' || xxx.count); end;
※java 集合的 remove(),還有 javascript 陣列的 splice 在跑循環刪除時,如果有兩個以上連續的、資料一樣的元素,如上面的 b,此時判斷是 b 刪除會有問題,但在 PL/SQL 沒有這個問題
沒有留言:
張貼留言