Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Tránh thay đổi giá trị biến trong Stored Procedure MySQL khi cập nhật bản ghi?

Vấn đề

Trong Stored Procedure, khi dùng biến người dùng (@variable) để lưu giá trị trước khi UPDATE, giá trị biến sẽ thay đổi sau khi UPDATE vì nó tham chiếu đến cùng một cột.

Giải pháp: Sử dụng biến cục bộ (DECLARE)

Biến cục bộ (DECLARE myVar INT) lưu giá trị snapshot tại thời điểm SELECT, không bị ảnh hưởng bởi UPDATE sau đó.

Ví dụ minh họa

Tạo bảng

mysql> CREATE TABLE DemoTable (
    Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Value INT
);

mysql> INSERT INTO DemoTable(Value) VALUES(100);

Stored Procedure sai (dùng @variable)

DELIMITER //
CREATE PROCEDURE updateValue_Wrong()
BEGIN
    SELECT @myValue := (SELECT Value FROM DemoTable WHERE Id = 1);
    SELECT @myValue;  -- 100
    
    UPDATE DemoTable SET Value = 200 WHERE Id = 1;
    
    SELECT @myValue := (SELECT Value FROM DemoTable WHERE Id = 1);
    SELECT @myValue;  -- 200 (đã thay đổi!)
END //
DELIMITER ;

Stored Procedure đúng (dùng DECLARE)

DELIMITER //
CREATE PROCEDURE updateValue_Correct()
BEGIN
    DECLARE myValue INT;
    
    SELECT Value INTO myValue FROM DemoTable WHERE Id = 1;
    SELECT myValue;  -- 100 (snapshot)
    
    UPDATE DemoTable SET Value = 200 WHERE Id = 1;
    
    SELECT myValue;  -- Vẫn là 100 (giữ nguyên snapshot)
    
    -- Nếu muốn giá trị mới:
    SELECT Value INTO myValue FROM DemoTable WHERE Id = 1;
    SELECT myValue;  -- 200
END //
DELIMITER ;

So sánh kết quả

Gọi procedure sai

mysql> CALL updateValue_Wrong();
+----------+
| @myValue |
+----------+
| 100      |
+----------+
+----------+
| @myValue |
+----------+
| 100      |
+----------+
+----------+
| @myValue |
+----------+
| 200      |  <-- Đã thay đổi!
+----------+
+----------+
| @myValue |
+----------+
| 200      |
+----------+

Gọi procedure đúng

mysql> CALL updateValue_Correct();
+----------+
| myValue  |
+----------+
| 100      |
+----------+
+----------+
| myValue  |
+----------+
| 100      |  <-- Giữ nguyên snapshot
+----------+
+----------+
| myValue  |
+----------+
| 200      |  <-- Chỉ sau khi SELECT INTO lại
+----------+

Tóm tắt

Loại biếnCú phápPhạm viHành vi khi UPDATE
User variable@varSessionThay đổi theo dữ liệu real-time
Local variableDECLARE var TYPEProcedure/BlockGiữ giá trị snapshot

Kết luận: Luôn dùng DECLARE + SELECT ... INTO để lưu snapshot giá trị trong Stored Procedure.