下準備として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 件のコメント:
コメントを投稿