IBM® Informix® 12.10

カーソルを使用した削除

カーソルを使用して、取り出した最後の行を削除するように、DELETE 文を記述することもできます。この方法で行を削除すると、次の例に示すように、WHERE 節でテストできない条件に基づいて削除をプログラムすることができます。次の例は、トランザクションの始まりと終わりをセットアップする方法のため、ANSI 標準準拠ではないデータベースにのみ適用されます。
警告: この例の Informix® ESQL/C 関数の設計では、プログラムがいつでも完全に動作すると は限りません。この関数が正しく動作するかどうかは、現在の排他レベルに依存しています。排他レベルについては後述します。排他レベルの詳細については、マルチユーザ環境のためのプログラミング を参照してください。たとえ意図したとおりに関数が動作しても、その効果は表の行の物理的な順序に依存するため、一般的な意味で適切な設計と言えません。
int delDupOrder()
{
   int ord_num;
   int dup_cnt, ret_code;

   EXEC SQL declare scan_ord cursor for
      select order_num, order_date
         into :ord_num, :ord_date
         from orders for update;
   EXEC SQL open scan_ord;
   if (sqlca.sqlcode != 0) 
      return (sqlca.sqlcode);
   EXEC SQL begin work;
   for(;;)
   {
      EXEC SQL fetch next scan_ord;
      if (sqlca.sqlcode != 0) break;
      dup_cnt = 0; /* default in case of error */
      EXEC SQL select count(*) into dup_cnt from orders
         where order_num = :ord_num;
      if (dup_cnt > 1)
      {
         EXEC SQL delete from orders
            where current of scan_ord;
         if (sqlca.sqlcode != 0) 
            break;
      }
   } 
   ret_code = sqlca.sqlcode;
   if (ret_code == 100)             /* merely end of data */
      EXEC SQL commit work;
   else      /* error on fetch or on delete */
      EXEC SQL rollback work;
   return (ret_code);
}

この関数の目的は、重複した注文番号を含む行を削除することです。デモンストレーション データベースでは、orders.order_num の列番号に一意性インデックスが指定されているため、注文番号が重複する可能性はありません。しかし、類似した関数が行に設定する別のデータベース用に書き込まれている可能性はあります。この場合、使用済みの列名が指定されます。

この関数は、表 orders のすべての行を走査するカーソルとして、scan_ord を宣言しています。このカーソルは FOR UPDATE 節で宣言されていますが、これは、カーソルがデータの変更に使用できることを示しています。カーソルが正しくオープンした場合は、この関数はトランザクションを開始し、表の各行を反復処理します。この関数は、表の各行について、埋込み SELECT 文を使用して、現在行と注文番号が同じ行が表に何行あるかを調べます。マルチユーザ環境のためのプログラミングで説明するように、この手順は、排他レベルが正しくないと失敗します。

デモンストレーション データベースでは、この表に一意性インデックスが付いているため、dup_cnt に戻されるカウント、つまり重複行の数は常に 1 です。この値が 1 よりも大きい場合は、この関数は表の現在行を削除して、カウント数を 1 減らします。

このような目的で使用される関数は、この例より高度な設計を必要とします。この関数は、データベース サーバが戻す最後の重複行以外のすべての重複行を削除します。この順番は、行の内容や意味とはまったく関係がありません。前出の例の関数は、カーソル宣言に ORDER BY 節を追加することで改善することができます。ただし、ORDER BY 節と FOR UPDATE 節を同時に使用することはできません。挿入の例で、より適切な方法を説明します。


フィードバックの送信 | 例の共有 | トラブルシューティング

PDF を見つけるには、Publications for the IBM Informix 12.10 family of products を参照してください。
リリース ノート、ドキュメント ノート、マシン ノートについては、リリース ノート・ページを参照してください。
タイムスタンプ リリース日: 2013 年 3 月