2012-08-10 41 views
5

Tôi đang sử dụng PL/SQL (Oracle 11g) để cập nhật cột lương bảng EMPLOYEES.sử dụng câu lệnh FOR UPDATE

Tôi đã sử dụng hai tập lệnh riêng biệt để thực hiện điều tương tự, tức là cập nhật mức lương của nhân viên.

Một tập lệnh sử dụng câu lệnh FOR UPDATE OF khi tập lệnh khác không sử dụng tập lệnh đó. Trong cả hai trường hợp, tôi thấy rằng oracle giữ các khóa mức hàng cho đến khi chúng ta thực hiện các lệnh ROLLBACK hoặc COMMIT.

Vậy sự khác biệt giữa hai tập lệnh là gì?

Loại nào tốt hơn để sử dụng?

Dưới đây là hai kịch bản tôi đang nói về:

-- Script 1: Uses FOR UPDATE OF 

declare 
cursor cur_emp 
is 
select employee_id,department_id from employees where department_id = 90 for update of salary; 
begin 
    for rec in cur_emp 
    loop 
    update Employees 
    set salary = salary*10 
    where current of cur_emp; 
    end loop; 
end; 


--Script 2: Does the same thing like script 1 but FOR UPDATE OF is not used here 

declare 
cursor cur_emp 
is 
select employee_id,department_id from employees where department_id = 90; 
begin 
    for rec in cur_emp 
    loop 
    update Employees 
    set salary = salary*10 
    where Employee_ID = rec.employee_id; 
    end loop; 
end; 

tôi thấy rằng Oracle mua lại ổ khóa cấp hàng trên cả hai trường hợp. Vì vậy, lợi ích của việc sử dụng FOR UPDATE OF là gì và cách nào tốt hơn là viết mã?

+2

Đừng quên: nếu nhân viên == mrp sau đó đặt mức lương + = 100000 – stark

Trả lời

12

Khi bạn chỉ định FOR UPDATE, hàng bị khóa tại điểm mà bạn SELECT dữ liệu. Nếu không có FOR UPDATE, hàng bị khóa tại điểm bạn UPDATE hàng. Trong tập lệnh thứ hai, một phiên khác có khả năng khóa hàng giữa thời gian SELECT được thực hiện và điểm mà bạn đã cố gắng để UPDATE nó.

Nếu bạn đang xử lý câu lệnh SELECT trả về một số hàng tương đối và vòng lặp chặt chẽ, có khả năng sẽ không có sự khác biệt đáng kể giữa hai hàng. Việc thêm một số FOR UPDATE vào số SELECT cũng mang đến cho bạn cơ hội thêm điều khoản thời gian chờ nếu bạn không muốn tập lệnh chặn không giới hạn nếu một số phiên khác xảy ra có một trong những hàng bạn đang cố cập nhật bị khóa.

+0

Không phải tập lệnh 'FOR UPDATE' sẽ chạy nhanh hơn khi truy cập cập nhật thông qua' ROWID' trong mệnh đề 'WHERE CURRENT OF'? – Ollie

+2

@Ollie - Có thể. Nhưng 'SELECT' phải truy cập mọi hàng để thiết lập thuộc tính lock trước khi nó trả về hàng đầu tiên, vì vậy nó sẽ liên quan đến việc đánh mỗi hàng một lần thứ hai (mặc dù lần truy cập thứ hai có khả năng nằm trong một đối tượng được lưu trữ). Tôi mong đợi hai người sẽ bù đắp lẫn nhau. Ngoài ra, nếu mục tiêu là tối đa hóa tốc độ, bạn sẽ viết một câu lệnh 'UPDATE' đơn hoặc ít nhất là các hoạt động hàng loạt PL/SQL, thay vì một vòng lặp' FOR' con trỏ theo từng hàng. –

Các vấn đề liên quan