DELETE

DELETE ステートメントは、表またはビューから行を削除します。 INSTEAD OF DELETE トリガーが定義されていないビューから行を削除すると、そのビューの元になっている表から行が削除されます。そのようなトリガーが定義されていれば、代わりにこのトリガーが活動化されます。

このステートメントには、以下の 2 つの形式があります。

  • 検索 DELETE 形式。この形式は、1 つ以上の行を削除する場合に使用します。必要に応じて、削除される行を検索条件によって限定することができます。
  • 位置指定 DELETE 形式。この形式は、1 行だけ削除する場合に使用します。削除される行は、カーソルの現在位置によって決まります。

呼び出し

検索 DELETE ステートメントは、アプリケーション・プログラムに組み込めるほか、対話式に呼び出すこともできます。 位置指定 DELETE ステートメントは、アプリケーション・プログラムに組み込んで使用しなければなりません。どちらの形式も、動的に準備できる実行可能ステートメントです。

権限

このステートメントの権限 ID が保持する特権には、少なくとも以下の 1 つ が含まれていなければなりません。

  • ステートメントに指定された表またはビューに対して、
    • その表またはビューに対する DELETE 特権
    • 表やビューが入っているライブラリーに対する *EXECUTE システム権限
  • データベース管理者権限

検索 DELETE の検索条件 に、その表またはビューの列の参照が含まれている場合、そのステートメントの権限 ID によって保持される特権には、以下の 1 つも含まれていなければなりません。

  • その表またはビューについての SELECT 特権
  • データベース管理者権限

検索条件 に副照会が含まれている場合、ステートメントの権限 ID によって保持される特権には、少なくとも以下の 1 つも含まれていなければなりません。

  • その副照会で識別されている各表またはビューについて、
    • 表やビューに対する SELECT 特権、および
    • 表やビューが入っているライブラリーに対する *EXECUTE システム権限
  • データベース管理者権限

SQL 特権に対応するシステム権限については『表またはビューへの権限を検査する際の対応するシステム権限』を参照してください。

構文

検索 DELETE:

構文図を読む構文図をスキップする
>>-DELETE FROM--+-table-name-+--+--------------------+---------->
                '-view-name--'  '-correlation-clause-'   

>--+-------------------------+---------------------------------->
   '-WHERE--search-condition-'   

   .---------------------------------------------.   
   V                                         (1) |   
>----+-------------------------------------+-----+-------------><
     +-isolation-clause--------------------+         
     '-concurrent-access-resolution-clause-'         

注:
  1. 同じ文節を複数回指定することはできません。

位置指定 DELETE:

構文図を読む構文図をスキップする
>>-DELETE FROM--+-table-name-+--+--------------------+---------->
                '-view-name--'  '-correlation-clause-'   

>--WHERE CURRENT OF--cursor-name-------------------------------><

構文図を読む構文図をスキップする
isolation-clause

|--WITH--+-NC-+-------------------------------------------------|
         +-UR-+   
         +-CS-+   
         +-RS-+   
         '-RR-'   

説明

FROM table-name または view-name
行を削除する表またはビューを識別します。 この名前は、現行サーバーに存在している表またはビューを識別していなければなりませんが、 カタログ表、カタログ表のビュー、または削除不可のビューを識別するものであってはなりません。 削除可能なビューの説明については、CREATE VIEWを参照してください。
correlation-clause
search-condition の中で表またはビューを指定するために使用できる代替名を指定します。相関文節 の説明については、照会を参照してください。相関名 の説明については、相関名を参照してください。
WHERE
削除する行を指定します。文節を省略するか、あるいは検索条件 またはカーソル名 を指定できます。 この文節を指定しなかった場合は、指定した表またはビューのすべての行が削除されます。
search-condition
検索条件で述べた検索条件です。副照会以外の検索条件 で指定する列名 は、該当する表またはビューの列を識別するものでなければなりません。

検索条件 は、表またはビューの各行に適用されます。削除される行は、検索条件 の結果が真になった行です。

検索条件 に副照会が含まれている場合は、行に検索条件 が適用されるたびにその副照会が実行され、検索条件 を適用する際に結果が使用されるたびに、その副照会が実行されると考えることができます。 実際に、相関参照のない副照会は一度しか実行されないことがありますが、相関参照を伴う副照会は各行ごとに一度実行する必要がある場合があります。

副照会が DELETE ステートメントのオブジェクト・テーブル、あるいは、CASCADE、SET NULL、または SET DEFAULT の削除規則を使用して従属表を参照する場合、その副照会は、行が削除される前に、完全に評価されます。

CURRENT OF cursor-name
削除操作で使用するカーソルを識別します。 この cursor-name は、宣言されているカーソルを識別しなければなりません。カーソルの宣言については、DECLARE CURSOR ステートメントの Notes の項を参照してください。

識別された表またはビューは、カーソルの選択ステートメント の FROM 文節でも指定されなければならず、カーソルは削除可能でなければなりません。 削除可能なカーソルの説明については、DECLARE CURSORを参照してください。

変更の始まりDECLARE CURSOR ステートメントには、DELETE ステートメントで使用される表またはビューの period-specification があってはなりません。変更の終わり

DELETE ステートメントが実行される時点では、カーソルはある 1 行 (削除される行) に位置付けられていなければなりません。 削除後、カーソル位置はその結果表の次の行の前になります。 次の行がない場合、カーソル位置は最後の行の後になります。

isolation-clause
このステートメントに関して使用する分離レベルを指定します。
WITH
分離レベルを指定します。次のいずれかになります。
  • RR 反復可能読み取り
  • RS 読み取り固定
  • CS カーソル固定
  • UR 非コミット読み取り
  • NC コミットなし
ISOLATION 文節 を指定しなかった場合は、デフォルトの分離レベルが使用されます。 デフォルトの分離レベルについての詳細は、ISOLATION 文節を参照してください。
concurrent-access-resolution-clause
SELECT ステートメントで使用する並行アクセスの解決方法を指定します。詳しくは、concurrent-access-resolution-clauseを参照してください。

DELETE の規則

トリガー:識別された表または識別されたビューの基本表が削除トリガーを持つ場合 、トリガーが起動します。トリガーが起動された結果、他のステートメントが実行されたり、削除された値に基づいてエラー条件が返されたりすることがあります。

参照保全: 識別された表、または識別された表の基本表が親表である場合、選択された行は、RESTRICT または NO ACTION の削除規則との関係において従属関係を持ってはなりません。 また、その DELETE は、RESTRICT または NO ACTION の削除規則との関係において従属関係を持つ下層行にカスケードしてはなりません。

削除操作が、RESTRICT または NO ACTION 削除規則によって防止されない場合には、選択された行は削除されます。 選択された行に従属する行は、いずれも影響を受けます。

  • SET NULL の削除規則に関連する行の従属行の外部キーのNULL 可能な列は、NULL 値に設定されます。
  • CASCADE の削除規則に関連する行の従属行はいずれも削除され、それらの行についても上記の規則が適用されます。
  • SET DEFAULT の削除規則に関連する行の従属行の外部キーの列は、対応するデフォルト値に設定されます。

参照制約 (RESTRICT 削除規則を伴う参照制約以外の) は、ステートメントの終わりで実際上チェックされます。 複数行削除の場合、これは、すべての行が削除され、何らかの関連トリガー が起動された後で起こります。

検査制約: 検査制約を指定することにより、親表と従属表の関係について SET NULL または SET DEFAULT の削除規則が設定されている場合に、親表の行が削除されないようにすることができます。親表の行のどれかを削除したときに、従属表の中の列が NULL または デフォルト値に設定されることになり、その NULL またはデフォルト値が原因で 検査制約の検索条件の評価結果が偽になる場合は、その行は削除されません。

削除操作エラー: なんらかの削除操作を実行しているときにエラーが起きた場合は、 このステートメントからの変更、参照制約、およびトリガー された SQL ステートメントはロールバックされます (ただし、このステートメントまたは 他のトリガーされた SQL ステートメントの分離レベルが NC である場合を除きます)。

ロック: 適切なロックが既に存在している場合を除き、 正常な DELETE ステートメントの実行の過程で、1 つ以上の排他ロックが獲得されます。 コミット操作またはロールバック操作によりロックが解除されるまでは、DELETE 操作の効果を認識できるのは以下のものだけです。

  • 削除を行ったアプリケーション・プロセス
  • 分離列 UR または NC を使用している他のアプリケーション・プロセス

ロックは、他のアプリケーション・プロセスがその表の操作を行うのを防止します。 ロックの詳細については、COMMIT、ROLLBACK、および LOCK TABLE の各ステートメントの説明、および 分離レベルを参照してください。

アプリケーション・プロセスが、その非更新可能なカーソルのいずれかが位置づけられている行を削除する場合、それらのカーソルはそれらの結果表の次の行の前に位置付けられます。 次の行 R の前に位置付けられるカーソルが C であると想定します (OPEN、C を介した DELETE、他のカーソルを介した DELETE、または検索 DELETE の結果として)。 R の派生元である基本表に作用する INSERT、 UPDATE、および DELETE 操作が発生すると、C を参照する次の FETCH 操作では、必ずしも、R 上に C を置くとは限りません。例えば、この操作で C を R' 上に置く可能性があります。この場合の R' とは、その時点で結果表の次の行になる新しい行です。

COMMIT(*RR)、COMMIT(*ALL)、COMMIT(*CS)、または COMMIT(*CHG) を指定している場合、1 つの DELETE ステートメントで削除または変更できる行の最大数は 4000000 です。 変更された行の数には、トリガー、CASCADE、SET NULL、または SET DEFAULT 参照保全削除規則の結果として、同じコミットメント定義のもとで挿入、更新、または削除された行はいずれも含まれます。

カーソルの位置: アプリケーション・プロセスが、カーソルのいずれかが位置づけられている行を削除する場合、それらのカーソルはそれらの結果表の次の行の前に位置付けられます。行 R の前に位置付けられるカーソルが C であると想定します (OPEN、C を介した DELETE、他のカーソルを介した DELETE、または検索 DELETE の結果として)。R の派生元である基本表に作用する INSERT、UPDATE、および DELETE 操作が発生すると、C を参照する次の FETCH 操作では、必ずしも、R 上に C を置くとは限りません。例えば、この操作で C を R' 上に置く可能性があります。この場合の R' とは、その時点で結果表の次の行になる新しい行です。

削除された行の数: DELETE ステートメントが完了すると、削除された行の数が、 SQL 診断域 (または SQLCA の SQLERRD(3)) の ROW_COUNT 条件領域項目に戻されます。 ROW_COUNT 項目の値には、CASCADE 削除規則またはトリガーの結果として削除された行の数は含まれません。

SQLCA についての説明は、SQLCA (SQL 連絡域)を参照してください。

DELETE パフォーマンス: WHERE 文節を含まない SQL DELETE ステートメントは、表のすべての行を削除します。この場合、消去操作 (コミットメント制御下で実行していない場合) または ファイル変更操作 (コミットメント制御下で実行している場合) を使用して行を削除することができます。 コミットメント制御下で実行している場合、 削除をそのままコミットするかロールバックすることができます。 このインプリメンテーションは、個別に各行を削除するよりもより高速ですが、 各行の個別のジャーナル項目はジャーナルに記録されません。 この技法を使用するのは、以下のすべてが当てはまる場合のみです。

  • ターゲット表はビューではありません。
  • 変更の始まりターゲット表はシステム期間テンポラル表ではありません。変更の終わり
  • かなりの行数を削除中です。
  • DELETE ステートメントを発行するジョブには、 ファイルにオープン・カーソルがありません (疑似クローズされた SQL カーソルを含まない)。
  • 他のジョブで表に対してロックをかけていません。
  • 表は、アクティブな削除トリガーを持っていません。
  • 表は、CASCADE、SET NULL、または SET DEFAULT 削除規則を使用した参照制約内の親ではありません。
  • DELETE ステートメントを発行するユーザーは、 DELETE 特権に加えて表の *OBJMGT または *OBJALTER システム権限を持っています。
  • SQL_FAST_DELETE_ROW_COUNT QAQQINI オプションは高速削除 を許可します。

この方法が正常に完了すると、増分数 (CHGPF CL コマンドの SIZE キーワードを参照) がゼロに設定されます。

表からすべての行を削除するには、TRUNCATE ステートメント を使用できます。

参照保全に関する考慮事項: SQL 診断域 (または SQLCA の SQLERRD(5)) の DB2_ROW_COUNT_SECONDARY 条件情報項目は、 参照制約によって影響を受けた行の数を示します。 この値には、CASCADE 削除規則の結果として削除された行の数、および SET NULL または SET DEFAULT 削除規則の結果として、その外部キーが NULL またはデフォルト値に設定された行の数が含まれます。

DB2_ROW_COUNT_SECONDARY についての説明は、GET DIAGNOSTICSを参照してください。SQLCA についての説明は、SQLCA (SQL 連絡域)を参照してください。

行アクセス制御が適用されている表の行の 削除: 行アクセス制御が適用されている表に対して DELETE ステートメントが 発行されると、有効な行の許可に指定されている規則によって、行が 削除可能かどうかが判定されます。 通常、これらの規則は、ステートメントの許可 ID に基づきます。以下に、有効になっている行の許可および列マスクが DELETE 時にどのように使用されるかについて説明します。
  • 行の許可を使用して、削除する行のセットが特定されます。

    1 つの表に対して、有効な行の許可が複数定義されている場合は、有効になっている各許可の検索条件に論理 OR 演算子を適用することにより、行アクセス制御検索条件が導出されます。 この行アクセス制御検索条件が表に適用されて、DELETE ステートメントの許可 ID でアクセス 可能な行が決定されます。 DELETE ステートメントに WHERE 節が指定されている場合、アクセス可能な行にユーザー指定の述部が適用されて、削除する行が 決定されます。WHERE 節がない場合、削除する行は、すべてのアクセス可能な行です。

変更の始まり

システム期間テンポラル表に関する考慮事項: DELETE ステートメントに履歴表を参照する (履歴表の名前の明示的な参照、または FROM 節での期間指定の使用による暗黙的な参照) 相関副照会が含まれる検索条件がある場合、履歴行として格納された削除行がそれらの行の削除操作で参照され、その後ステートメントで処理される可能性があります。

CURRENT TEMPORAL SYSTEM_TIME 特殊レジスターが NULL 以外の値に設定され、SYSTIME オプションの値が YES の場合は、DELETE ステートメントの基礎ターゲットを、システム期間テンポラル表にしてはなりません。 この制限は、システム期間テンポラル表への参照が直接か間接かにかかわらず適用されます。

履歴表に関する考慮事項: システム期間テンポラル表の 1 つの行が削除されるとき、その行の履歴コピーが対応する履歴表に挿入され、履歴行の終了タイム・スタンプが、データ変更操作の時刻に対応するシステム判別値の形式でキャプチャーされます。 データベース・マネージャーが割り当てるこの値は、次のいずれかの場合に時刻機構を読み取ることによって生成されます。(1) トランザクションの中で、表に含まれる行開始列またはトランザクション開始 ID 列に値を割り当てる必要があるようなデータ変更ステートメントを最初に実行するとき。(2) システム期間テンポラル表に含まれる行を削除するとき。 終了列の値は、トランザクション全体の履歴表で固有になるようにデータベース・マネージャーによって生成されます。 履歴表に挿入される行の終了タイム・スタンプ値が開始タイム・スタンプ値より大きくなるように、タイム・スタンプ値が調整される可能性があります。これは、競合するトランザクションがシステム期間テンポラル表の同じ行を更新しているときに行われる場合があります。このタイム・スタンプ値の調整を行うには、SYSTIME_PERIOD_ADJ QAQQINI オプションを *ADJUST に設定する必要があります。 存在しない場合は、エラーが戻されます。

削除操作では、この調整は、関連付けられたシステム期間テンポラル表の行終了列に対応する、履歴表の終了列の値にのみ影響があります。 この表への以降の参照では、関連付けられたシステム期間テンポラル表の期間 SYSTEM_TIME の行開始列および行終了列においてトランザクション開始時刻が検索される場合に、上記の調整を考慮に入れてください。

履歴表が ON DELETE ADD EXTRA ROW で定義された場合、削除が実行される前の行のバージョンが履歴表に追加されます。 この行が追加される際に、行開始列、行終了列、および生成式列の値が生成されます。 この情報は、行の削除時点を表します。

変更の終わり

REXX: 変数は、REXX プロシージャー内の DELETE ステートメントでは使用できません。その代わりとして、DELETE は、パラメーター・マーカーを使用して PREPARE と EXECUTE のオブジェクトにする必要があります。

代替構文: 以下のキーワードは、旧リリースとの互換性を維持するためにサポートされている同義語です。 これらのキーワードは標準キーワードではないので、原則として使用しないようにしてください。

  • キーワード NONE を NC の同義語として使用することができます。
  • キーワード CHG を UR の同義語として使用することができます。
  • キーワード ALL を RS の同義語として使用することができます。
  • FROM キーワードはオプションです。

例 1: 表 DEPARTMENT から、部門 (DEPTNO) ‘D11’ を削除します。

   DELETE FROM DEPARTMENT
     WHERE DEPTNO = 'D11'

例 2: 表 DEPARTMENT から、すべての部門を削除します (つまり、表を空にします)。

   DELETE FROM DEPARTMENT

例 3: Java プログラム・ステートメントを使用して、接続コンテキスト「ctx」上の PROJECT 表から、ホスト変数 HOSTDEPT の部門 (java.lang.String) と等しい部門 (DEPTNO) のすべてのサブプロジェクト (MAJPROJ が NULL のもの) を削除します。

   #sql [ctx] { DELETE FROM PROJECT
                  WHERE DEPTNO = :HOSTDEPT 
                  AND MAJPROJ IS NULL };

例 4: 以下の例に示す Java プログラム (一部分) は、 退職した社員 (JOB) を表示し、要求があれば、接続コンテキスト 'ctx' 上にある EMPLOYEE 表から 特定の社員を削除します。

   #sql iterator empIterator implements sqlj.runtime.ForUpdate
        ( ... );
   empIterator C1;

   #sql [ctx] C1 = { SELECT * FROM EMPLOYEE
                       WHERE JOB = 'RETIRED' };

   #sql {  FETCH C1 INTO ...     };
   while ( !C1.endFetch() )  {
      System.out.println( ... );
                  ...
      if ( condition for deleting row ) {
          #sql [ctx] { DELETE FROM EMPLOYEE
                         WHERE CURRENT OF C1  };
      }
      #sql { FETCH C1 INTO ...     };
   }
   C1.close();