6.1 静的SQLの説明
6.1.1 文
PL/SQLの静的SQL文を次に示します。特に説明がないかぎり、これらの文の構文は、対応するSQL文と同じです。
-
SELECT(この文は問合せとも呼ばれます)PL/SQL構文の詳細は、「SELECT INTO文」を参照してください。
-
データ操作言語(DML)文:
-
INSERTPL/SQL構文の詳細は、「INSERT文の拡張機能」を参照してください。
-
UPDATEPL/SQL構文の詳細は、「UPDATE文の拡張機能」を参照してください。
-
DELETEPL/SQL構文の詳細は、「DELETE文の拡張機能」を参照してください。
-
MERGE(構文の詳細は、『Oracle Database SQL言語リファレンス』を参照)
ノート:
『Oracle Database SQL言語リファレンス』におけるDMLの定義とは異なります。
-
-
トランザクション制御言語(TCL)文:
-
COMMIT(構文の詳細は、『Oracle Database SQL言語リファレンス』を参照) -
ROLLBACK(構文の詳細は、『Oracle Database SQL言語リファレンス』を参照) -
SAVEPOINT(構文の詳細は、『Oracle Database SQL言語リファレンス』を参照) -
SETTRANSACTION(構文の詳細は、『Oracle Database SQL言語リファレンス』を参照)
-
-
LOCKTABLE(構文の詳細は、『Oracle Database SQL言語リファレンス』を参照)
PL/SQLの静的SQL文では、対応するSQLでバインド変数のプレースホルダを使用できる場合は、PL/SQLの識別子を使用できます。PL/SQLの識別子は、変数または仮パラメータを示している必要があります。
表名や列名などに対してPL/SQL識別子を使用するには、「システム固有の動的SQL」で説明されているEXECUTE IMMEDIATE文を使用します
ノート:
PL/SQLコードによってDML文が実行された後、変数の値が未定義になるものがあります。たとえば:
-
FETCH文またはSELECT文で例外が呼び出された場合、その文の後の定義変数値は未定義になります。 -
行が処理されないDML文の後、そのDML文が
BULKまたは複数行にわたる操作でなければ、OUTバインド変数の値は未定義になります。
例6-1 静的SQL文
この例では、PL/SQLの無名ブロックで3つのPL/SQL変数を宣言し、静的SQL文のINSERT、UPDATE、DELETEでそれらを使用しています。このブロックでは、静的SQL文COMMITも使用しています。
DROP TABLE employees_temp; CREATE TABLE employees_temp AS SELECT employee_id, first_name, last_name FROM employees; DECLARE emp_id employees_temp.employee_id%TYPE := 299; emp_first_name employees_temp.first_name%TYPE := 'Bob'; emp_last_name employees_temp.last_name%TYPE := 'Henry'; BEGIN INSERT INTO employees_temp (employee_id, first_name, last_name) VALUES (emp_id, emp_first_name, emp_last_name); UPDATE employees_temp SET first_name = 'Robert' WHERE employee_id = emp_id; DELETE FROM employees_temp WHERE employee_id = emp_id RETURNING first_name, last_name INTO emp_first_name, emp_last_name; COMMIT; DBMS_OUTPUT.PUT_LINE (emp_first_name || ' ' || emp_last_name); END; /
結果:
Robert Henry
6.1.2 疑似列
疑似列は、表の列のように動作しますが、表には格納されません。
制限などの擬似列の一般情報は、『Oracle Database SQL言語リファレンス』を参照してください。
静的SQLには、次のSQL疑似列が含まれます。
-
CURRVALおよびNEXTVAL(詳細は、「PL/SQLのCURRVALおよびNEXTVAL」を参照)。 -
LEVEL(詳細は、『Oracle Database SQL言語リファレンス』を参照) -
OBJECT_VALUE(詳細は、『Oracle Database SQL言語リファレンス』を参照)関連項目:
トリガーにおける
OBJECT_VALUEの使用方法の詳細は、「OBJECT_VALUE疑似列」を参照してください -
ROWID(詳細は、『Oracle Database SQL言語リファレンス』を参照) -
ROWNUM(詳細は、『Oracle Database SQL言語リファレンス』を参照)
6.1.2.1 PL/SQLのCURRVALおよびNEXTVAL
順序が作成されると、SQL文の中でCURRVAL疑似列を使用してその値にアクセスできます(この場合、その順序の現在の値が戻ります)。また、NEXTVAL疑似列を使用してもアクセスできます(この場合は、順序が増加され、新しい値が戻ります)。
これらの疑似列を参照するには、ドット表記法(sequence_name.CURRVALなど)を使用します。
ノート:
sequence_name.NEXTVALを参照するたびに、トランザクションをコミットするかロールバックするかにかかわらず、順序はすぐに増分され、その変化は永続的になります。
PL/SQL式では、NUMBER式を使用できる場所であればどこでも、sequence_name.CURRVALおよびsequence_name.NEXTVALを使用できます。ただし、次のことに注意してください:
-
sequence_name.CURRVALまたはsequence_name.NEXTVALを使用してADTメソッド・パラメータのデフォルト値を指定すると、コンパイル・エラーが発生します。 -
PL/SQLは、出現するすべての
sequence_name.CURRVALおよびsequence_name.NEXTVALを評価します(これらが出現するすべての行に対して順序式を評価するSQLとは異なります)。
関連項目:
-
順序の概要は、『Oracle Database SQL言語リファレンス』を参照してください
-
CURRVALおよびNEXTVALの構文の詳細は、『Oracle Database SQL言語リファレンス』
例6-2 擬似列CURRVALおよびNEXTVAL
この例では、順序HR.EMPLOYEES_SEQの順序番号を生成し、複数の文でその番号を参照しています。
DROP TABLE employees_temp; CREATE TABLE employees_temp AS SELECT employee_id, first_name, last_name FROM employees; DROP TABLE employees_temp2; CREATE TABLE employees_temp2 AS SELECT employee_id, first_name, last_name FROM employees; DECLARE seq_value NUMBER; BEGIN -- Generate initial sequence number seq_value := employees_seq.NEXTVAL; -- Print initial sequence number: DBMS_OUTPUT.PUT_LINE ( 'Initial sequence value: ' || TO_CHAR(seq_value) ); -- Use NEXTVAL to create unique number when inserting data: INSERT INTO employees_temp (employee_id, first_name, last_name) VALUES (employees_seq.NEXTVAL, 'Lynette', 'Smith'); -- Use CURRVAL to store same value somewhere else: INSERT INTO employees_temp2 VALUES (employees_seq.CURRVAL, 'Morgan', 'Smith'); /* Because NEXTVAL values might be referenced by different users and applications, and some NEXTVAL values might not be stored in database, there might be gaps in sequence. */ -- Use CURRVAL to specify record to delete: seq_value := employees_seq.CURRVAL; DELETE FROM employees_temp2 WHERE employee_id = seq_value; -- Update employee_id with NEXTVAL for specified record: UPDATE employees_temp SET employee_id = employees_seq.NEXTVAL WHERE first_name = 'Lynette' AND last_name = 'Smith'; -- Display final value of CURRVAL: seq_value := employees_seq.CURRVAL; DBMS_OUTPUT.PUT_LINE ( 'Ending sequence value: ' || TO_CHAR(seq_value) ); END; /