記録
23203 ワード
記録は、1行の複数列のスカラーで構成され、複合データ構造である。
PL/SQLは3種類の記録タイプをサポートしています。テーブルベースの記録、ラベルベースの記録、ユーザー独自の記録です。
一、表による記録
ユーザー定義のレコードを作成するシンタックスは以下の通りです。
1>記録タイプを宣言する場合、あるフィールドにNOT NULL制約を指定すると、そのフィールドを初期化しなければなりません。例えば上記の例では、フィールドがcurr_であればdateはNOT NULL制約、つまりcurr_を指定しています。date DATE NOT NULLは、エラーを報告します。PLS-00218:a variable declead NOT NULL must have an initialization assignment。初期化可能:curr_date DATE NOT NULL:=sysdate。
2> 記録は全体的に空と判断することはできません。記録フィールドだけを判断することができます。
3> 記録は全体的に比較できません。記録フィールドだけを比較することができます。
4>テーブルまたはラベルベースの記録全体をユーザーがカスタマイズした記録に割り当てることができます。両方が同じ構造を持つ限り。しかし、ユーザーがカスタマイズした記録については、2つのカスタムレコードが同じ構造を持っていても、タイプが違っていて、全体的に値を付けられません。以下の通りです
SQL>/name_rec 2:=name_rec 1;*ERROR at line 15:ORA-0650:line 15,column 17:PLS-0082:expression is of wrong typeORA-0650:line 15,column 4:PL/SQL:Sttement ignored
二つの記録は同じ構造を持っていますが、各記録の種類が違っています。この記録も互換性がなく、全体の割当値がエラーとなります。
上記の例は次のように変更できます。
ネスト記録とは、他の記録とセットを含む記録のことです。
例えば:
統合例:
一、部門番号を入力し、その部門の従業員を出力する
Enter value for v_deptno:10 old 14:v_deptno NUMBER(2)=&v_deptno;new 14:v_deptno NUMBER(2):=10;Deptno:10 Employees:CLARKINGMILLER
PL/SQL procedure success fully complected.
二、各部門の従業員総数を出力する
RESEARCH DALLAS 5 SALES CHICAGO 7 ACCOUNTING NEW YORK 3
PL/SQL procedure success fully complected.
PL/SQLは3種類の記録タイプをサポートしています。テーブルベースの記録、ラベルベースの記録、ユーザー独自の記録です。
一、表による記録
DECLARE
emp_rec emp%rowtype;
BEGIN
SELECT * INTO emp_rec FROM emp WHERE empno=7788;
DBMS_OUTPUT.PUT_LINE('Ename is: '||emp_rec.ename);
DBMS_OUTPUT.PUT_LINE('Job is: '||emp_rec.job);
DBMS_OUTPUT.PUT_LINE('Salary is: '||emp_rec.sal);
END;
二、ランドマークによる記録DECLARE
CURSOR emp_cur IS SELECT * FROM emp WHERE rownum <=4;
emp_rec emp_cur%ROWTYPE;
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO emp_rec;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Ename is: '||emp_rec.ename);
DBMS_OUTPUT.PUT_LINE('Job is: '||emp_rec.job);
DBMS_OUTPUT.PUT_LINE('Salary is: '||emp_rec.sal);
END LOOP;
END;
三、ユーザーがカスタマイズしたレコードユーザー定義のレコードを作成するシンタックスは以下の通りです。
TYPE type_name IS RECORD
(field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION],
field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],
...
field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);
record_name TYPE_NAME;
一例を挙げてみますDECLARE
TYPE time_rec_type IS RECORD
(curr_date DATE,
curr_day VARCHAR2(12),
curr_time VARCHAR(8) :='00:00:00'
);
time_rec TIME_REC_TYPE;
BEGIN
SELECT sysdate INTO time_rec.curr_date FROM dual;
time_rec.curr_day := TO_CHAR(time_rec.curr_date,'DAY');
time_rec.curr_time := TO_CHAR(time_rec.curr_date,'HH24:MI:SS');
DBMS_OUTPUT.PUT_LINE('Date: '||time_rec.curr_date);
DBMS_OUTPUT.PUT_LINE('Day: '||time_rec.curr_day);
DBMS_OUTPUT.PUT_LINE('Time: '||time_rec.curr_time);
END;
注意:1>記録タイプを宣言する場合、あるフィールドにNOT NULL制約を指定すると、そのフィールドを初期化しなければなりません。例えば上記の例では、フィールドがcurr_であればdateはNOT NULL制約、つまりcurr_を指定しています。date DATE NOT NULLは、エラーを報告します。PLS-00218:a variable declead NOT NULL must have an initialization assignment。初期化可能:curr_date DATE NOT NULL:=sysdate。
2> 記録は全体的に空と判断することはできません。記録フィールドだけを判断することができます。
3> 記録は全体的に比較できません。記録フィールドだけを比較することができます。
4>テーブルまたはラベルベースの記録全体をユーザーがカスタマイズした記録に割り当てることができます。両方が同じ構造を持つ限り。しかし、ユーザーがカスタマイズした記録については、2つのカスタムレコードが同じ構造を持っていても、タイプが違っていて、全体的に値を付けられません。以下の通りです
DECLARE
TYPE name_type1 IS RECORD
(first_name VARCHAR2(15),
last_name VARCHAR2(30)
);
TYPE name_type2 IS RECORD
(first_name VARCHAR2(15),
last_name VARCHAR2(15)
);
name_rec1 name_type1;
name_rec2 name_type2;
BEGIN
name_rec1.first_name := 'John';
name_rec1.last_name := 'Smith';
name_rec2 := name_rec1;
END;
運転報告は以下のエラーです。SQL>/name_rec 2:=name_rec 1;*ERROR at line 15:ORA-0650:line 15,column 17:PLS-0082:expression is of wrong typeORA-0650:line 15,column 4:PL/SQL:Sttement ignored
二つの記録は同じ構造を持っていますが、各記録の種類が違っています。この記録も互換性がなく、全体の割当値がエラーとなります。
上記の例は次のように変更できます。
DECLARE
TYPE name_type1 IS RECORD
(first_name VARCHAR2(15),
last_name VARCHAR2(30)
);
name_rec1 name_type1;
name_rec2 name_type1;
BEGIN
name_rec1.first_name := 'John';
name_rec1.last_name := 'Smith';
name_rec2 := name_rec1;
END;
上記全体の割当の制限は、ユーザがカスタマイズした記録タイプに限られます。両方が同じ構造を持つ限り、テーブルまたはラベルに基づく記録全体の割当値をユーザーがカスタマイズした記録に与えることができる。DECLARE
CURSOR dept_cur IS SELECT * FROM dept;
TYPE dept_type IS RECORD
(deptno dept.deptno%TYPE,
dname dept.dname%TYPE,
loc dept.loc%TYPE
);
dept_rec1 dept%ROWTYPE; -- table-based record
dept_rec2 dept_cur%ROWTYPE; -- cursor-based record
dept_rec3 dept_type;
BEGIN
-- Populate table-based record
SELECT * INTO dept_rec1 FROM dept WHERE deptno=10;
dept_rec2 := dept_rec1;
dept_rec3 := dept_rec1;
--Populate cursor-based record
OPEN dept_cur;
LOOP
FETCH dept_cur INTO dept_rec2;
EXIT WHEN dept_cur%NOTFOUND;
END LOOP;
dept_rec1 := dept_rec2;
dept_rec3 := dept_rec2;
--Populate user defined record
SELECT * INTO dept_rec3 FROM dept WHERE deptno=20;
dept_rec1 := dept_rec3;
dept_rec2 := dept_rec3;
END;
四、ネスト記録ネスト記録とは、他の記録とセットを含む記録のことです。
例えば:
DECLARE
TYPE name_type IS RECORD
(first_name VARCHAR2(15);
last_name VARCHAR2(30));
TYPE person_type IS RECORD
(name name_type;
street VARCHAR2(50);
city VARCHAR2(25);
state VARCHAR2(2);
zip VARCHAR2(5));
person_rec person_type;
このコードには2つのユーザのカスタム記録タイプが含まれています。ここで、2番目のユーザがカスタム記録タイプのperson(u)typeはネストされた記録タイプで、そのフィールドnameがname_であるためです。typeタイプのレコード。統合例:
一、部門番号を入力し、その部門の従業員を出力する
DECLARE
TYPE ename_type IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
TYPE dept_info_type IS RECORD
(deptno emp.deptno%TYPE,
ename_tab ename_type);
CURSOR name_cur (p_deptno number) IS
SELECT ename
FROM emp
WHERE deptno = p_deptno;
dept_info_rec dept_info_type;
v_deptno NUMBER(2) := &v_deptno;
v_counter INTEGER := 0;
BEGIN
dept_info_rec.deptno := v_deptno;
DBMS_OUTPUT.PUT_LINE('Deptno: '||dept_info_rec.deptno||chr(10)||'Employees:');
FOR name_rec IN name_cur(v_deptno) LOOP
v_counter := v_counter+1;
dept_info_rec.ename_tab(v_counter) := name_rec.ename;
END LOOP;
FOR i IN 1..dept_info_rec.ename_tab.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(dept_info_rec.ename_tab(i));
END LOOP;
END;
出力結果は: Enter value for v_deptno:10 old 14:v_deptno NUMBER(2)=&v_deptno;new 14:v_deptno NUMBER(2):=10;Deptno:10 Employees:CLARKINGMILLER
PL/SQL procedure success fully complected.
二、各部門の従業員総数を出力する
DECLARE
CURSOR dept_cur IS
SELECT dname,loc,count(*) total
FROM dept,emp
WHERE dept.deptno=emp.deptno
GROUP BY dname,loc;
TYPE dname_rec_type IS RECORD
(dname dept.dname%TYPE,
loc dept.loc%TYPE,
total INTEGER);
TYPE dept_type IS TABLE OF dname_rec_type INDEX BY BINARY_INTEGER;
dept_tab dept_type;
v_counter INTEGER :=0;
BEGIN
FOR dept_rec IN dept_cur LOOP
v_counter := v_counter+1;
dept_tab(v_counter).dname := dept_rec.dname;
dept_tab(v_counter).loc := dept_rec.loc;
dept_tab(v_counter).total := dept_rec.total;
DBMS_OUTPUT.PUT_LINE(dept_tab(v_counter).dname||' '||dept_tab(v_counter).loc
||' '||dept_tab(v_counter).total);
END LOOP;
END;
出力結果は:RESEARCH DALLAS 5 SALES CHICAGO 7 ACCOUNTING NEW YORK 3
PL/SQL procedure success fully complected.