文法関連

  NULL文



   NULL文は、アクションを起こさないことを明示的に指定するとき
   に使用します。NULL文は制御を次の文に渡すことしかしません。
   しかし、これによってコードを分かりやすくすることができます。
   代替アクションが指定できるような構成体では、NULL文がプレイ
   スホルダの役割を果たします。読み手に対して、代替アクション
   を誤って見逃したのではなく、実際にアクションが不要であると
   いうことを伝えることができます。次のNULL文は、名前を持たな
   い例外に対してアクションが不要であることを示しています。

  
   ...
   EXCEPTION
    WHEN ZERO_DIVIDE THEN
          ROLLBACK;
      WHEN VALUE_ERROR THEN
          INSERT INTO errors VALUES ...
          COMMIT;
      WHEN OTHERS THEN
          NULL;
   END;

  

   IF文のすべての句には、少なくとも1つの実行可能文がなければな
   りません。NULL文は実行可能文なので、アクションが不要な状況
   に対応する句で使用することができます。次の例では、NULL文によ
   って、成績優秀な従業員だけがボーナスを受け取ることが分かりや
   すくなっています。

  
   IF rating > 90 THEN
       compute_bonus(emp_id);
   ELSE
       NULL;
   END IF;
  

   また、NULL文は、アプリケーションをトップ・ダウンで設計する際
   に、「スタブ(切り株の意)」を作成するのにも使えます。スタブは
   ダミーのサブプログラムで、これを使用することによってメイン・
   プログラムのテストとデバッグが終了するまで、プロシージャとフ
   ァンクションの定義をしないで済ますことが可能となります。次の
   例では、NULL文によって、サブプログラムの実行部に、少なくとも
   1つの文が存在しなければならないという条件を解決しています。

  
   PROCEDURE debit_account (acct_id IN INTEGER, amount IN REAL) IS
   BEGIN
       NULL;
   END debit_account;
  



  %NOTFOUNDのサンプル






  ROWID (Oracle7)

  

        内部的に、Oracleデータベースは、すべて「行ID」と呼ばれる
        6バイトのバイナリ値を格納するROWID型の疑似列を持ちます。
        行IDは行を一意に識別するので、これを使うと特定の行に最も
        速くアクセスすることができます。ROWIDデータ型を使用すると
        、行IDを読み取り可能な形式で格納することができます。

        ROWIDはCHARのサブタイプです。このため、行IDを選択してまた
        は取り出してROWID型変数に入れるときには、関数ROWIDTOCHAR
        を使います。この関数は、バイナリ値を18バイトの文字列に変
        換して、次の形式で戻します。

        BBBBBBBB.RRRR.FFFF

        BBBBBBBBはデータ・ファイル中のブロック、RRRRはブロック中
        の行(最初の行が0です)、FFFFはデータ・ファイルです。これら
        の数値は16進数です。たとえば、次の行IDは、7番目のデータ・
        ファイルの15番目のブロックの11番目の行を指します。

        0000000E.000A.0007

        一般に、ROWID型変数は、カーソルが取り出した最後の行を識別
        するために、UPDATE文またはDELETE文のWHERE句の中でROWID型の
        疑似列と比較されます。第4章の「コミット間での取り出し」の
        節に例があります。

  



  連結演算子

  

        連結演算子(||)は文字列を他の文字列に連結します。たとえば、
        次の式は、

        'suit' || 'case'

        次の値を戻します。

        'suitcase'

        CHAR型のオペランドだけが渡された場合、連結演算子はCHAR型の
        値を戻します。CHAR型のオペランドだけではない場合は、VARCHA
        R2型の値を戻します。

        連結演算子はNULLオペランドを無視します。たとえば、次の式は、

        'apple' || NULL || 'sauce'

        次の値を戻します。

        'applesauce'
  



  DECODE関数

  

        function DECODE (expr, search1, result1 [,search2, result2] ...
           [default] )

        式exprが、それぞれのsearch値と比較されます。exprがあるsearch
        値と等しいと、対応するresultが戻されます。一致するものがなけ
        れば、DECODEはdefault値を戻します。default値が指定されていな
        ければNULLを戻します。

        式exprとしては任意のデータ型が指定できますが、search値はexpr
        と同じデータ型でなければなりません。戻される値はresult1と同じ
        データ型に強制的に変換されます。DECODEはSQL文においてのみ使用
        可能です。


        関数DECODEは、先頭の引数を1つまたは複数の検索式と比較します。
        検索式は結果式と対になっています。検索式や結果式はNULLの場合
        があります。検索に成功すると、対応する結果が戻されます。次の
        例で、ratingの値が3ならば、DECODEは値1000を戻します。

        credit_limit := DECODE(rating, NULL, 1000, 'B', 2000, 'A', 4000);
  



  コメント

  

        1)  1行コメント 

        1行コメントは、行の中の任意の位置にある二重ハイフン(--)
        から始まり、その行の終わりまで続きます。次に例を示します。

        -- begin processing
        SELECT sal INTO salary FROM emp  -- get current salary
                WHERE empno = emp_id;
        bonus := salary * 0.15;  -- compute bonus amount

        コメントは、行の末尾ならば文の途中でも使用できることに
        注意してください。プログラムのテストやデバッグを行う際に、
        コード中の1つの行を使用不能にしたい場合があります。行を
        「コメントにする」方法を次の例に示します。

        -- DELETE FROM emp WHERE comm IS NULL;


        2)  複数行コメント 

        複数行コメントは、スラッシュ-アスタリスク(/*)で始まり、
        アスタリスク-スラッシュ(*/)で終わります。複数の行にまた
        がってもかまいません。
  



  ユーザファンクション

  

        ファンクションとは、値を計算するサブプログラムのことです。
        ファンクションとプロシージャは同じような構造を持ちますが、
        ファンクションの方はRETURN句を持っています。次にファンク
        ションの構文を示します。


        FUNCTION name [ (argument [, argument, ...]) ] RETURN datatype IS
            [local declarations]
        BEGIN
            executable statements
        [EXCEPTION
            exception handlers]
        END [name];

        argumentには次の構文を使用します。

        var_name [IN | OUT | IN OUT] datatype [{:= | DEFAULT} value]

        引数宣言のデータ型指定子には制約を付けてはなりません。

        プロシージャと同様に、ファンクションも仕様部と本体の2つの部
        分を持ちます。ファンクションの仕様部はキーワードFUNCTIONで始
        め、結果の値のデータ型を指定するRETURN句で終えます。引数宣言
        はオプションです。引数を取らないファンクションではカッコを書
        きません。

        ファンクションの本体はキーワードISで始めキーワードENDで終え
        ます。ENDの後には、オプションとしてファンクション名を続ける
        ことができます。ファンクションの本体には宣言部、実行部および
        オプションの例外処理部という3つの部分があります。

        宣言部では、キーワードISとBEGINの間にローカル宣言を置きます。
        キーワードDECLAREは使用しません。実行部では、キーワードBEGIN
        とEXCEPTION(またはEND)の間に文を置きます。ファンクションの実
        行部には、1つまたは複数のRETURN文が存在しなければなりません。
        例外処理部では、キーワードEXCEPTIONとENDの間に例外ハンドラを
        置きます。


        ファンクションは式の一部として呼び出されます。たとえば、ファ
        ンクションsal_okは次のようにして呼び出すことができます。


        IF sal_ok(new_sal, new_title) THEN
           ...
        END IF;
        ...
        promotable := sal_ok(new_sal, new_title) AND (rating > 3);

        いずれの場合も、ファンクション識別子は結果を戻す式の役目を持ちます。


        ユーザー定義のファンクションは、プロシージャ文では呼び出せま
        すが、SQL文では呼び出すことができません。たとえば、次のINSERT文
        は不正です。

        DECLARE
            empnum  INTEGER;
            ...
            FUNCTION bonus (emp_id INTEGER) RETURN REAL IS
            BEGIN ... END bonus;
        BEGIN
            ...
            INSERT INTO payroll
                VALUES (empnum, ..., bonus(empnum));  -- illegal call
        END;
  



  LOOP文とEXIT文

  

        LOOP文を使用すると、一連の文を複数回実行することができます。
        LOOP文には、LOOP、WHILE-LOOPおよびFOR-LOOPという3つの形式が
        あります。


        【LOOP】 

        LOOP文の最も単純な形式は、キーワードLOOPとEND LOOPで一連の
        文を囲む基本(または無限)ループです。次に例を示します。


        LOOP
                sequence_of_statements;
        END LOOP;

        ループが繰り返されるごとに、一連の文が実行され、制御はルー
        プの先頭に戻ります。処理の続行が望ましくない場合、または不可
        能になった場合は、EXIT文を使ってループを終了させることができ
        ます。ループの中では、任意の場所に1つまたは複数のEXIT文を置
        くことができます。ただし、ループの外には置くことができません。
        EXIT文には、EXITおよびEXIT-WHENという2つの形式があります。


        【EXIT】 

        EXIT文はループを無条件に終了させます。EXIT文が現れると、ルー
        プはただちに終了し、制御は次の文に移ります。次に例を示します。


        LOOP
                ...
                IF ... THEN
                        ...
                        EXIT;  -- exit loop immediately
                END IF;
        END LOOP;
        -- control resumes here


        【EXIT-WHEN 】

        EXIT-WHEN文を使用すると、ループを条件に合わせて終了させること
        ができます。EXIT文が現れると、WHEN句の中の条件が評価されます。
        条件がTRUEに評価されると、ループは終了し、制御はループの後の文
        に移ります。次に例を示します。

        LOOP
                FETCH c1 INTO ...
                EXIT WHEN c1%NOTFOUND;  -- exit loop if condition is true 
                 ...
        END LOOP;
        CLOSE c1;
  



  ループ・ラベル

  
PL/SQLブロックと同様に、ループにもラベルを付けることができます。
ラベルは二重の山カッコで囲んだ未宣言の識別子で、次に示すように
LOOP文の先頭に置きます。


<<label_name>>
LOOP
        sequence_of_statements;

END LOOP;

次の例のように、オプションとして、ループ文の末尾にもラベル名を
付けることができます。


<<my_loop>>
LOOP
   ...
END LOOP my_loop;

ラベル付きのループをネストする場合は、末尾のラベルを使って分か
りやすくすることができます。

どちらの形式のEXIT文でも、現在のループに限らず、任意の外側のル
ープも終了させることができます。終了させたい外側のループにラベ
ルを付け、そのラベルをEXIT文で使用してください。次に例を示します。


<<outer>>
LOOP
    ...
    LOOP
        ...
        EXIT outer WHEN ...  -- exit both loops
    END LOOP;
    ...
END LOOP outer;

ラベルを付けた外側のループが、内側のループを含めて終了されます。
  



  WHILE-LOOP

  

        WHILE-LOOP文は、キーワードLOOPとEND LOOPで囲まれた一連の文
        に条件を結び付けます。次に例を示します。


        WHILE condition LOOP
            sequence_of_statements;
        END LOOP;

        ループを反復する前に条件が評価されます。条件がTRUEに評価さ
        れれば、一連の文が実行され、制御がループの先頭に戻ります。
        条件がFALSEまたはNULLに評価されると、ループは実行されず、
        制御は次の文に移ります。次に例を示します。


        WHILE total <= 25000 LOOP
            ...
            SELECT sal INTO salary FROM emp WHERE ...
            total := total + salary;
        END LOOP;

        反復の回数は条件に依存し、ループが終了してみないと分かりませ
        ん。条件はループの先頭でテストされるため、一連の文が一度も実
        行されない可能性もあります。上の例でtotalの初期値が25000より
        も大きいと、条件がFALSEに評価されてループは実行されません。

        いくつかの言語は、条件をループの先頭ではなく末尾でテストする
        LOOP UNTIL構造または REPEAT UNTIL構造を持っています。この場合、
        一連の文は少なくとも一度は実行されます。PL/SQLにはこうした構
        造はありませんが、次のようにすれば簡単に作ることができます。


        LOOP
            sequence_of_statements;
            EXIT WHEN boolean_expression;
        END LOOP;
  



  FOR-LOOP

  

        WHILEループの反復回数はループが終了するまでは分かりませんが、
        FORループの反復回数はループに入る前から分かっています。FORル
        ープは指定された整数の範囲で実行を繰り返します。範囲はキーワ
        ードFORとLOOPで囲まれる「反復スキーム」の一部です。次に構文
        を示します。

        FOR counter IN [REVERSE] lower_bound..higher_bound LOOP
            sequence_of_statements;
        END LOOP;

        範囲はFORループに入ったときに評価され、それ以降は再評価されま
        せん。次の例に示すように、一連の文は範囲中の整数1つについて1
        回実行されます。繰り返しが1回起こるごとに、ループ・カウンタが
        1つ増やされます。


        FOR i IN 1..3 LOOP  -- assign the values 1,2,3 to i
            sequence_of_statements;  -- executes three times
        END LOOP;


        次の例のように、下限が上限と等しければ、一連の文は1回だけ実行
        されます。

        FOR i IN 3..3 LOOP  -- assign the value 3 to i
            sequence_of_statements;  -- executes one time
        END LOOP;

        デフォルトでは、反復は下限から上限の向きに進みます。しかし、
        次の例のように、キーワードREVERSEを使用すると、反復は上限から
        下限の向きに進みます。繰り返しが1回起こるごとに、ループ・カウ
        ンタが1つ減らされます。

        FOR i IN REVERSE 1..3 LOOP  -- assign the values 3,2,1 to i

            sequence_of_statements;  -- executes three times
        END LOOP;

        この場合でも、範囲の上限と下限は(降順ではなく)昇順に書きます。

        FORループの中では、ループ・カウンタを定数のように参照すること
        ができます。次に示すように、ループ・カウンタは式の中でも使用で
        きますが、値を代入することはできません。
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        FOR ctr IN 1..10 LOOP
            ...
            IF NOT finished THEN
                INSERT INTO ... VALUES (ctr, ...);  -- legal
                factor := ctr * 2;  -- legal
        
                ...
            ELSE
                ctr := 10;  -- illegal
            END IF;
        END LOOP;


        次に示すように、PL/SQLではループの繰り返し範囲を実行時に動的
        に決定することができます。


        SELECT COUNT(empno) INTO emp_count FROM emp;

        FOR i IN 1..emp_count LOOP
            ...
        END LOOP;

        emp_countの値はコンパイル時には未定で、SELECT文が実行時に戻し
        ます。


        ループ・カウンタは、INTEGER型のローカル変数として暗黙的に宣言さ
        れているので、明示的に宣言する必要はありません。次の例では、ロ
        ーカル宣言がグローバル宣言を隠しています。


        DECLARE
            ctr  INTEGER;
        BEGIN
            ...
            FOR ctr IN 1..25 LOOP
                ...
                IF ctr > 10 THEN ...  -- refers to loop counter
            END LOOP;
        END;

        この例でグローバル変数を使用するには、次のようにラベルとピリオ
        ド記号を使用する必要があります。


        <<main>>
        DECLARE
            ctr  INTEGER;
            ...
        BEGIN
            ...
            FOR ctr IN 1..25 LOOP
        
                ...
                IF main.ctr > 10 THEN ...  -- refers to global variable
            END LOOP;
        END main;

        ネストされたFORループにも同じ有効範囲の規則が適用されます。次の
        例を考えてみてください。どちらのループ・カウンタも同じ名前を持っ
        ています。このため、内側のループから外側のループ・カウンタを参
        照するには、次のようにラベルとピリオド記号を使用する必要があります。


        <<outer>>
        FOR step IN 1..25 LOOP
            FOR step IN 1..10 LOOP

                ...
                IF outer.step > 15 THEN ...
            END LOOP;
        END LOOP outer;
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ