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

Biến người dùng (User-defined) vs Biến cục bộ (Local Variable) trong MySQL

MySQL có 2 loại biến chính: **Biến người dùng (User-defined variables / Session variables)** và **Biến cục bộ (Local variables)**. Chúng khác biệt về phạm vi, vòng đời và cách khai báo.

Bảng so sánh nhanh

Đặc điểmBiến người dùng (@var)Biến cục bộ (DECLARE)
Ký hiệuBắt đầu bằng @ (vd: @x)Không có @ (vd: x)
Phạm viSession (kết nối)Trong block BEGIN...END (stored proc, function, trigger)
Vòng đờiTồn tại suốt session, hủy khi ngắt kết nốiTồn tại trong lần gọi procedure, hủy khi kết thúc
Khởi tạo lạiGiữ giá trị giữa các lần gọi procKhởi tạo lại mỗi lần gọi proc
Khai báoSET @x = 1 hoặc SELECT @x := 1DECLARE x INT DEFAULT 1
Độ kiểu (typing)Loosely typed (tự động)Strongly typed (phải khai báo kiểu)
Truy cập chéo sessionKhông (session A không thấy @x của session B)N/A

Biến người dùng (User-defined variables)

Cách gán giá trị

-- Cách 1: SET (khuyên dùng)
SET @ten_bien = gia_tri;
SET @x = 10, @y = 'hello', @z = NOW();

-- Cách 2: SELECT với := (phép gán)
SELECT @x := 10;
SELECT @ten := 'Nguyen Van A', @tuoi := 25;

-- ⚠️ Sai: SELECT @x = 10 → Đây là SO SÁNH (trả về 0/1), KHÔNG gán giá trị
SELECT @x = 10;  -- Kết quả: 0 (FALSE) vì @x chưa có giá trị

Ví dụ: Giá trị giữ lại giữa các lần gọi

SET @counter = 0;

SELECT @counter := @counter + 1 AS lan_1;  -- 1
SELECT @counter := @counter + 1 AS lan_2;  -- 2
SELECT @counter := @counter + 1 AS lan_3;  -- 3

Biến cục bộ (Local variables)

Chỉ dùng trong Stored Program (Procedure, Function, Trigger)

DELIMITER //
CREATE PROCEDURE DemoLocalVariable()
BEGIN
    DECLARE x INT DEFAULT 10;   -- Khai báo + khởi tạo
    DECLARE y VARCHAR(20);      -- Khai báo, mặc định NULL
    
    SET x = x + 5;              -- Gán giá trị
    SELECT x AS ket_qua;        -- 15
END //
DELIMITER ;

CALL DemoLocalVariable();  -- Mỗi lần gọi, x luôn bắt đầu = 10

Ví dụ so sánh trực tiếp trong Stored Procedure

Tạo procedure demo cả 2 loại

DELIMITER //
CREATE PROCEDURE sp_LocalVsUserVariable()
BEGIN
    DECLARE local_var INT DEFAULT 10;   -- Local variable
    SET local_var = local_var + 10;     -- 20
    
    SET @user_var = @user_var + 10;     -- User variable (cần SET trước)
    
    SELECT local_var AS local_variable;
    SELECT @user_var AS user_variable;
END //
DELIMITER ;

Khởi tạo user variable

SET @user_var = 10;

Lần gọi thứ 1

CALL sp_LocalVsUserVariable();
-- local_variable = 20 (10+10)
-- user_variable  = 20 (10+10)

Lần gọi thứ 2

CALL sp_LocalVsUserVariable();
-- local_variable = 20 (Khởi tạo lại 10, +10 = 20)
-- user_variable  = 30 (Giữ 20 từ lần trước, +10 = 30)

Lần gọi thứ 3

CALL sp_LocalVsUserVariable();
-- local_variable = 20 (Luôn reset về 10+10)
-- user_variable  = 40 (Tích lũy: 30+10)

Khi nào dùng loại nào?

Dùng biến người dùng (@var) khi:

  • Cần chia sẻ giá trị giữa nhiều stored procedure trong cùng session
  • Truyền giá trị từ client → stored proc → client
  • Tính toán tích lũy qua nhiều bước/lần gọi
  • Debug: SELECT @var; bất cứ đâu trong session

Dùng biến cục bộ (DECLARE) khi:

  • Logic nội bộ stored procedure/function
  • Cần kiểu dữ liệu chặt chẽ (INT, VARCHAR(50), DECIMAL(10,2)...)
  • Tránh xung đột tên biến giữa các procedure
  • Code an toàn, dễ bảo trì, tuân thủ chuẩn SQL

Lưu ý quan trọng

  • Biến người dùng không thể dùng trong Function (chỉ Procedure)
  • Biến cục bộ phải khai báo ở đầu block BEGIN (trước mọi statement khác)
  • Tên biến không phân biệt hoa/thường: @X = @x
  • Giá trị mặc định của DECLARE là NULL nếu không có DEFAULT