レコードタイプとは、論理的に関連するデータを一つの単位として格納するものであり、少なくとも1つのスカラータイプまたはRECORDデータ型のメンバーを含みます。これをPLRECORDのフィールド(FIELD)と呼び、互いに異なるが論理的に関連する情報を格納する役割を果たします。
適用対象
この内容はOceanBaseデータベースEnterprise Editionにのみ適用されます。OceanBaseデータベースCommunity EditionはMySQLモードのみを提供します。
レコード変数の初期値を記録する
RECORD タイプのレコード変数については、定義時に別の初期値が指定されていない限り、各フィールドの初期値は NULL です。
%ROWTYPE または %TYPE で宣言されたレコード変数については、各フィールドの初期値は NULL です。この変数は参照する項目の初期値を継承しません。
レコード定数を宣言する
レコード定数を宣言するには、まず関数を作成してレコードを初期化し、その後定数宣言内でその関数を呼び出す必要があります。
以下の例を参照してください:
obclient> CREATE OR REPLACE PACKAGE my_rec_types IS
TYPE rec IS RECORD (a NUMBER, b NUMBER,k NUMBER);
FUNCTION init_rec RETURN rec;
END my_rec_types;
/
Query OK, 0 rows affected
obclient> CREATE OR REPLACE PACKAGE BODY my_rec_types IS
FUNCTION init_rec RETURN rec IS
c_rec REC;
BEGIN
c_rec.a := 111;
c_rec.b := 222;
c_rec.k := 333;
RETURN c_rec;
END init_rec;
END my_rec_types;
/
Query OK, 0 rows affected
obclient> DECLARE
r CONSTANT my_rec_types.rec := my_rec_types.init_rec();
BEGIN
DBMS_OUTPUT.PUT_LINE('r.a = ' || r.a);
DBMS_OUTPUT.PUT_LINE('r.b = ' || r.b);
DBMS_OUTPUT.PUT_LINE('r.k = ' || r.k);
END;
/
Query OK, 0 rows affected
r.a = 111
r.b = 222
r.k = 333
レコードタイプ
PLブロック内で定義されるRECORDタイプはローカルタイプです。
パッケージヘッダー内で定義されるRECORDタイプは公開RECORDタイプです。package_name.type_nameを使用してパッケージ名を限定することで、パッケージ外部から参照できます。データベースに格納されており、DROP PACKAGEステートメントでプログラムパッケージを削除すると、RECORDタイプも一緒に削除されます。
SchemaレベルでRECORDタイプを作成することはできません。したがって、RECORDタイプはADT属性データ型にすることはできません。
RECORDタイプを定義する際には、その名前を指定し、フィールドタイプを定義する必要があります。フィールドを定義するには、その名前とデータ型を指定する必要があります。デフォルトでは、フィールドの初期値はNULLです。フィールドにNOT NULL制約を指定できます。この場合、初期値はNULL以外でなければなりません。NOT NULL制約がない場合、初期値にNULL以外であるという制限はありません。
パッケージヘッダー内で定義されたRECORDタイプは、同じ定義を持つローカルRECORDタイプと互換性がありません。
RECORD変数タイプを定義する際には、ストアドプロシージャがサポートするデータ型を使用するか、%TYPEメソッドを使用してテーブルまたはカーソル列のタイプをコピーできます。例:
DECLARE
TYPE region_record_type IS RECORD (
id REGIONS.region_id%TYPE,
name REGIONS.region_name%TYPE
);
region_record region_record_type;
OceanBaseデータベースでは、レコードは集合や配列などの他の複雑な型とネストして使用できます。
以下の例は、Varrayフィールドを持つRECORDタイプです。
DECLARE
TYPE empname IS VARRAY(3) OF VARCHAR2(20);
TYPE contact IS RECORD (
name empname := empname('Zhang','San','Feng'), -- Varrayフィールド
phone employees.phone_number%TYPE
);
emp contact;
BEGIN
emp.phone := '123456789';
DBMS_OUTPUT.PUT_LINE (
emp.name(1) || ' ' ||
emp.name(2) || ' ' ||
emp.name(3) || ', ' ||
emp.phone
);
END;/
Query OK, 0 rows affected
Zhang San Feng, 123456789
レコード変数
レコード変数には、単一のレコード変数と複合レコード変数が含まれます。
レコード変数の各フィールドに個別に値を代入できます。場合によっては、あるレコード変数の値を別のレコード変数に代入することもできます。レコード変数がデータベーステーブルまたはビューのすべてまたは一部の行を表す場合、その行をレコード変数に代入できます。
別の変数にレコード変数を代入する
あるレコード変数の値を別のレコード変数に代入できるのは、以下の条件を満たす場合に限ります:
2つの変数は同じ
RECORDタイプを持っている必要があります。ターゲット変数が
RECORDタイプで明示的に宣言されており、ソース変数が%ROWTYPEを使用してテーブルの行タイプで宣言されている場合、両者のフィールド数と順序が完全に一致している必要があります。また、対応する各フィールドも同じデータ型である必要があります。
コンストラクタを使用してレコード型変数に直接値を代入する例:
DECLARE
TYPE employee_record_type IS RECORD (
id employee.id%TYPE,
name employee.name%TYPE,
salary employee.salary%TYPE
);
-- コンストラクタ構文を使用した代入
v_employee_rec employee_record_type := employee_record_type(1, 'John Doe', 55000.00);
BEGIN
-- ここではv_employee_rec変数を使用できます
DBMS_OUTPUT.PUT_LINE('Employee: ' || v_employee_rec.name || ', Salary: ' || v_employee_rec.salary);
END;
/
各フィールドに個別に値を代入する例:
DECLARE
-- レコード型を宣言し、そのフィールドがemployeeテーブルの構造と同じであることを示します。
v_employee_rec employee%ROWTYPE;
BEGIN
-- 各フィールドに個別に値を代入します
v_employee_rec.id := 1;
v_employee_rec.name := 'John Doe';
v_employee_rec.salary := 55000.00;
-- レコード内の情報を出力します
DBMS_OUTPUT.PUT_LINE('Employee: ' || v_employee_rec.name || ', Salary: ' || v_employee_rec.salary);
END;
/
レコード変数にすべてまたは一部の行を割り当てる
レコード変数がデータベーステーブルまたはビューのすべてまたは一部の行を表す場合、対応する行をレコード変数に割り当てることができます。方法は以下のとおりです:
SELECT INTOを使用して行をレコード変数に代入する簡単な
SELECT INTO宣言の構文は次のとおりです:SELECT select_list INTO record_variable_name FROM table_or_view_name;select_list内の各列に対して、レコード変数には対応する型が互換性のあるフィールドが存在する必要があります。select_list内の列の順序は、レコードフィールドの順序と同じでなければなりません。FETCHを使用して行をレコード変数に代入する簡単な
FETCH宣言の構文は次のとおりです:FETCH cursor INTO record_variable_name;カーソルはクエリに関連付けられています。クエリで選択された各列に対して、レコード変数には対応する型が互換性のあるフィールドが存在する必要があります。カーソルは明示的カーソルまたは強型カーソル変数である必要があります。
SQLステートメントを使用してPLレコード変数に行を返す
RETURNING INTO句は、その句に属するステートメントが返す値を格納する変数を指定します。RETURNING INTO句を持つINSERT、UPDATE、およびDELETESQLステートメントは、PLレコード変数内の行データを返すことができます。
レコード変数にNULLを代入する
レコード変数に NULL を代入すると、その各フィールドにも NULL 値が代入されます。
この代入は再帰的であり、あるフィールドがレコードである場合、そのフィールドも NULL に代入されます。
レコードの作成
レコードの内部構成要素はフィールドと呼ばれ、レコードのフィールドにアクセスする際には「.」記号を使用します。書式は次のとおりです:レコード名.フィールド名。
レコードを作成する方法は以下の3種類があります:
RECORDタイプを宣言し、そのタイプの変数を宣言します。構文は以下のとおりです:TYPE record_name IS RECORD ( field_name data_type [:= initial_value] [, field_name data_type [:= initial_value ] ]... ); variable_name record_name;変数とタイプを宣言し、テーブルの行タイプに関連付けます。構文は以下のとおりです:
variable_name table_name%ROWTYPE ;説明
レコードのフィールドは、テーブルの列名とデータ型が一対一で対応します。
変数とタイプを宣言し、カーソルのタイプに関連付けます。構文は以下のとおりです:
variable_name cursor_name%ROWTYPE ;説明
レコードのフィールドは、カーソルの
SELECTクエリ内の列名とデータ型が一対一で対応していなければなりません。例:
obclient> DECLARE TYPE my_rec IS RECORD( code VARCHAR2(10), name VARCHAR2(50) NOT NULL :='book'); v_book MY_REC; BEGIN v_book.code :='10000'; v_book.name :='OceanBase PL Developer Guide'; DBMS_OUTPUT.PUT_LINE(v_book.code||': '||v_book.name); END; / Query OK, 0 rows affected 10000: OceanBase PL Developer Guide説明
レコード変数への操作は通常の変数と同じであり、
SELECT INTOステートメントを使用して代入することができます。