Oracle PL/SQL游標鎖定(FOR UPDATE)

使用FOR UPDATE進行游標鎖定進行資料更新

前言

游標的鎖定主要是為了處理資料交易,在游標處理資料的過程當中,不讓其他交易同時對資料進行異動的動作,一旦將資料被鎖定,除非進行COMMIT或是ROLLBACK才會解除鎖定,另外關閉游標亦可解除鎖定。

要使用游標鎖定需要使用「FOR UPDATE」語法,若單純使用「FOR UPDATE」則會將篩選回來的資料列皆進行鎖定,若只想針對篩選回來的資料進行部分資料欄位進行鎖定則須在後面在加上「OF 資料欄」即可。

實作

相關語法如下

1
CURSOR 游標名稱 IS SELECT 敘述 FOR UPDATE [OF 欄位1, 欄位2, 欄位3];

以下進行相關示範

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
DECLARE
    -- 宣告變數
    V_TITLE ARTICLE.TITLE%TYPE;
    -- 宣告 RECORD
    R_ARTICLE ARTICLE%ROWTYPE;
    -- 宣告游標
    CURSOR C_ARTICLE IS SELECT * FROM ARTICLE FOR UPDATE OF TITLE, MODIFY_DATE;
BEGIN
    -- 開啟游標
    OPEN C_ARTICLE;
    DBMS_OUTPUT.PUT_LINE('開啟游標');

    -- 提取資料
    FETCH C_ARTICLE INTO R_ARTICLE;
    DBMS_OUTPUT.PUT_LINE('提取資料');

    WHILE C_ARTICLE%FOUND LOOP
        -- 設定 V_TITLE 變數
        V_TITLE := '楊藝的洋溢生活 - ' || R_ARTICLE.TITLE;

        -- 調整 TITLE
        UPDATE ARTICLE SET TITLE = V_TITLE, MODIFY_DATE = SYSDATE  WHERE ID = R_ARTICLE.ID;
        DBMS_OUTPUT.PUT_LINE('ID: ' || R_ARTICLE.ID || ', TITLE: ' || R_ARTICLE.TITLE || '修改為:' || V_TITLE);

        -- 提取資料
        FETCH C_ARTICLE INTO R_ARTICLE;
    END LOOP;
    -- 確認交易並解除鎖定
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('確認交易');

    -- 關閉游標
    CLOSE C_ARTICLE;
    DBMS_OUTPUT.PUT_LINE('關閉游標');
END;

執行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
開啟游標
提取資料
ID: 7C5E3A5AD847F0D3E050A8C0FD894690, TITLE: 我的第一篇 PL/SQL 筆記修改為:楊藝的洋溢生活 - 我的第一篇 PL/SQL 筆記
ID: 7C5E3A5AD848F0D3E050A8C0FD894690, TITLE: 我的 JAVA 學習歷程修改為:楊藝的洋溢生活 - 我的 JAVA 學習歷程
ID: 7C5E3A5AD849F0D3E050A8C0FD894690, TITLE: C# 程式架構修改為:楊藝的洋溢生活 - C# 程式架構
ID: 7C5E3A5AD84AF0D3E050A8C0FD894690, TITLE: Eclipse 程式碼提示設定修改為:楊藝的洋溢生活 - Eclipse 程式碼提示設定
ID: 7C5E3A5AD84BF0D3E050A8C0FD894690, TITLE: TightVNC 檔案傳輸修改為:楊藝的洋溢生活 - TightVNC 檔案傳輸
ID: 7C5E3A5AD84CF0D3E050A8C0FD894690, TITLE: Apache Struts 2 檔案上傳修改為:楊藝的洋溢生活 - Apache Struts 2 檔案上傳
ID: 7C5E3A5AD84DF0D3E050A8C0FD894690, TITLE: Apache Struts 2 表單驗證 (驗證框架)修改為:楊藝的洋溢生活 - Apache Struts 2 表單驗證 (驗證框架)
ID: 7C5E3A5AD84EF0D3E050A8C0FD894690, TITLE: Apache Struts 2 攔截器設定與使用修改為:楊藝的洋溢生活 - Apache Struts 2 攔截器設定與使用
ID: 7C5E3A5AD84FF0D3E050A8C0FD894690, TITLE: MySQL 外部 IP 連線 (Ubuntu Server)修改為:楊藝的洋溢生活 - MySQL 外部 IP 連線 (Ubuntu Server)
ID: 7C5E3A5AD850F0D3E050A8C0FD894690, TITLE: CentOS 切換 root 免密碼設定修改為:楊藝的洋溢生活 - CentOS 切換 root 免密碼設定
確認交易
關閉游標