静的SQLの説明

静的SQLの構文は、特に説明がないかぎり、SQLと同じです。

ここでのトピック

PL/SQLの静的SQL文を次に示します。特に説明がないかぎり、これらの文の構文は、対応するSQL文と同じです。

PL/SQLの静的SQL文では、対応するSQLでバインド変数のプレースホルダを使用できる場合は、PL/SQLの識別子を使用できます。PL/SQLの識別子は、変数または仮パラメータを示している必要があります。

表名や列名などに対してPL/SQL識別子を使用するには、「システム固有の動的SQL」で説明されているEXECUTE IMMEDIATE文を使用します

ノート:

PL/SQLコードによってDML文が実行された後、変数の値が未定義になるものがあります。たとえば:

  • FETCH文またはSELECT文で例外が呼び出された場合、その文の後の定義変数値は未定義になります。

  • 行が処理されないDML文の後、そのDML文がBULKまたは複数行にわたる操作でなければ、OUTバインド変数の値は未定義になります。

例7-1 静的SQL文

この例では、PL/SQLの無名ブロックで3つのPL/SQL変数を宣言し、静的SQL文のINSERTUPDATEDELETEでそれらを使用しています。このブロックでは、静的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

擬似列

疑似列は、表の列のように動作しますが、表には格納されません。

制限などの擬似列の一般情報は、『Oracle Database SQL言語リファレンス』を参照してください。

静的SQLには、次のSQL疑似列が含まれます。

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とは異なります)。

関連項目:

例7-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;
/