カーソルの変更および削除操作とは、カーソルが位置づけた状態で、テーブル内の指定されたデータ行を変更または削除することを指します。
機能の適用範囲
この内容はOceanBaseデータベースEnterprise Editionにのみ適用されます。OceanBaseデータベースCommunity EditionはMySQLモードのみを提供します。
カーソルを使用したクエリステートメントでは、FOR UPDATEオプションを使用する必要があります。これにより、カーソルを開く際に、テーブル内の対応するデータ行のすべてまたは一部の列をロックできます。
FOR UPDATE句は、カーソル結果セットで選択された行をロックし、他のセッションによるデータの変更を防ぎます。他のセッションは、トランザクションの処理がコミットまたはロールバックされるまで、これらの行データにロックをかけることができません。
構文は以下のとおりです:
SELECT . . . FROM ... FOR UPDATE [OF column[, column]...] [NOWAIT]
別のセッションがアクティブセット内の行にロックをかけている場合、SELECT FOR UPDATE操作は、その他のセッションがロックを解除するまで待機し続けます。このような場合、NOWAIT句を追加すると、もしこれらの行が別のセッションによってロックされていると、OPENは直ちに終了し、次のエラーが発生します:OBE-30006: resource busy; acquire with WAIT timeout expired。
FOR UPDATEでカーソルを宣言すると、DELETEおよびUPDATEステートメントでWHERE CURRENT OF cursor_name句を使用して、カーソル結果セットの現在の行に対応するデータベーステーブル内のデータ行を変更または削除できます。
例:
obclient> SELECT empname, salary FROM emp WHERE deptno=4;
+---------+--------+
| EMPNAME | SALARY |
+---------+--------+
| Karen | 10000 |
| Guy | 10000 |
+---------+--------+
2 rows in set
obclient>DECLARE
V_deptno emp.deptno%TYPE :=4;
CURSOR c_emp IS SELECT empname, salary
FROM emp WHERE deptno=V_deptno FOR UPDATE NOWAIT;
BEGIN
FOR emp_record IN c_emp LOOP
IF emp_record.salary < 12000 THEN
UPDATE emp SET salary=12000 WHERE CURRENT OF c_emp;
END IF;
END LOOP;
END;
/
Query OK, 0 rows affected
obclient> SELECT empname, salary FROM emp WHERE deptno=4;
+---------+--------+
| EMPNAME | SALARY |
+---------+--------+
| Karen | 12000 |
| Guy | 12000 |
+---------+--------+
2 rows in set