カーソルの変更および削除操作とは、カーソルが特定の位置にある状態で、テーブル内の指定されたデータ行を変更または削除することを指します。
適用対象
この内容は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