我們有一個用於更新特定列的腳本。在這個腳本中,我們使用了一個FOR UPDATE
遊標。在腳本的第一個版本中,我們沒有使用FOR UPDATE
子句的OF
部分。正如我們發現here和here這不應該影響腳本,因爲所有連接表的所有行都應該被鎖定,因此可以更新。Oracle FOR UPDATE(OF)遊標行爲
但是,當我們在運行腳本時雖然打印了日誌消息,但未對列(column_a)進行更新。
當我們在光標有FOR UPDATE OF t1.column_a
的情況下更改腳本時,會出現相同的日誌消息,但更新是正確的!
任何人都可以解釋爲什麼沒有OF
子句的腳本不起作用嗎?
Oracle數據庫版本爲'Oracle Database 11g企業版版本11.2.0.3.0',也使用'Oracle Database 12c企業版版本12.1.0.2.0 - 64位'進行了測試。
這裏是執行腳本的一個簡單的版本:
BEGIN
-- anonymous procedure
DECLARE PROCEDURE update_column_a IS
c_to_find CONSTANT NUMBER := -42;
c_constant_value CONSTANT VARCHAR2 := 'value';
CURSOR c_my_cursor IS
SELECT t1.*
FROM table_1 t1, table_2 t2, table_3 t3
WHERE t1.t2_id = t2.id
AND t2.t3_id = t3.id
AND t3.column_b = c_to_find
-- FOR UPDATE with OF clause works
-- FOR UPDATE OF t1.column_a;
-- FOR UPDATE without OF clause does not
FOR UPDATE;
BEGIN
FOR cursor_rec IN c_my_cursor LOOP
IF cursor_rec.column_a IS NULL OR cursor_rec.column_a = '' THEN
dbms_output.put_line('Updating column...');
UPDATE t1 SET column_a = c_constant_value WHERE CURRENT OF c_my_cursor;
ELSE
dbms_output.put_line('Column already set...');
END IF;
END LOOP;
END update_column_a;
-- anonymous execution
BEGIN
update_column_a;
END;
END;
/
正如我所瞭解的文檔,這減少了對具有指定列的表的鎖定。根據該[網站](http://www.fast-track.cc/___aaa_pl_sql_cursor_for_update.htm)應該鎖定所有行。 '如果遊標將連接表,則兩個表中游標返回的所有行都被鎖定。' – sebastian
我們沒有得到任何異常。這也讓我們感到困惑,因爲它不會更新列。 – sebastian
我不會相信任何Don Burleson通常會發布的東西,但他似乎就在那裏! –