※物件
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 沒有這個問題
沒有留言:
張貼留言