下準備としてPLSQL SQL Developer からテーブル作成 で作成したMemberテーブルに3件ほどデータを作成します。
DECLARE BEGIN INSERT INTO Member ( MemberId, MemberName, Rank ) VALUES ( 1, 'Yamada', 'B'); INSERT INTO Member ( MemberId, MemberName, Rank ) VALUES ( 2, 'Tanaka', 'C'); INSERT INTO Member ( MemberId, MemberName, Rank ) VALUES ( 3, 'Suzuki', 'A'); END;
それではデータを1件抽出し変数に代入します。
DECLARE部でデータを代入する変数を宣言します。
次に「SELECT 列名 INTO 代入する変数」で取得したデータを変数に代入します。
データが取得できない場合や複数件取得できた場合はエラーになるので注意してください。
DECLARE memberid VARCHAR2(4); membername VARCHAR2(10); rank VARCHAR2(2); BEGIN SELECT MemberId, MemberName, Rank INTO memberid, membername, rank FROM Member WHERE MemberId = '1'; SYS.DBMS_OUTPUT.PUT_LINE('MemberId:' || memberid); SYS.DBMS_OUTPUT.PUT_LINE('MemberName:' || membername); SYS.DBMS_OUTPUT.PUT_LINE('Rank:' || rank); END;上記の例では変数のデータ型をSELECTで取得する列のデータ型と合わせる必要がありました。
memberid VARCHAR2(4);の「VARCHAR2(4)」部分です。
だけどイチイチ列のデータ型や精度を指定するのはメンドクサイよ!
仕様変更でデータ型や精度が変わるたびに修正するのはメンドクサイよ!
メンドクサイのはイヤなので上記の変数宣言のデータ型を「%type属性」を使用してちょっとラクします。
DECLARE memberid Member.MemberId%type; membername Member.MemberName%type; rank Member.Rank%type; BEGIN SELECT MemberId, MemberName, Rank INTO memberid, membername, rank FROM Member WHERE MemberId = '1'; SYS.DBMS_OUTPUT.PUT_LINE('MemberId:' || memberid); SYS.DBMS_OUTPUT.PUT_LINE('MemberName:' || membername); SYS.DBMS_OUTPUT.PUT_LINE('Rank:' || rank); END;Oracle Database PL/SQL言語リファレンスによりますと
『%TYPE属性を使用すると事前に宣言されている変数、フィールド、レコード、ネストした表またはデータベース列と同じデータ型の定数、変数、フィールドまたはパラメータを宣言できます。参照先項目が変更されると、宣言は自動的に更新されます。』とあります。
つまり「memberid Member.MemberId%type;」の部分は
MemberテーブルのMemberId列と同じデータ型にし、MemberテーブルのMemberId列のデータ型が変更されても自動的に変更するから大丈夫ということです。
う~ん
でもまだメンドクサイ。Memberテーブルの1データを取得するのに、Memberテーブルに含まれるすべての列分の変数を作るのはメンドクサイよ。
Memberテーブルの列が20列ぐらいあったら、変数も20個用意するの・・・・?ムリ。
ハイ!そんなときは「%ROWTYPE属性」を使用します。
DECLARE member_rec Member%rowtype; BEGIN SELECT * INTO member_rec FROM Member WHERE MemberId = '1'; SYS.DBMS_OUTPUT.PUT_LINE('MemberId:' || member_rec.MemberId); SYS.DBMS_OUTPUT.PUT_LINE('MemberName:' || member_rec.MemberName); SYS.DBMS_OUTPUT.PUT_LINE('Rank:' || member_rec.Rank); END;「レコード変数名 表名%ROWTYPE;」とすることでテーブルの1データを代入できる変数ができるんですね!
ステキです。
ステキですね~ラクですね~使いまくりたくなりますね~
でもダメなんですね~
今回Memberテーブルは3列しかないですが、Memberテーブルが20列あったとします。
そのうち使用するのは5列だったとしたら、15列分のデータは取得するけど無駄になってしまいます。
そんな場合は、使用する列だけのレコード型を自分で定義し、必要な列だけ変数に代入するようにします。
DECLARE --レコード型の作成 TYPE member_rec_type IS RECORD ( MemberId Member.MemberId%type, MemberName Member.MemberName%type ); --レコード型のレコード変数を宣言 member_rec member_rec_type; BEGIN SELECT MemberId, MemberName INTO member_rec FROM Member WHERE MemberId = '1'; SYS.DBMS_OUTPUT.PUT_LINE('MemberId:' || member_rec.MemberId); SYS.DBMS_OUTPUT.PUT_LINE('MemberName:' || member_rec.MemberName); END;「TYPE データ型名 IS RECORD (フィールド宣言・・・);」でレコードの「型」を宣言します。
次にデータ型が作成したレコード型の変数を宣言します。
レコード型を作成するのがメンドクサイですが、使い分けが必要なようです。
0 件のコメント:
コメントを投稿