Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL เก็บค่าจาก SELECT ไปใน User Variable (@variable)

กำหนดค่า User Variable จาก SELECT Statement

MySQL รองรับ User-Defined Variables (@var_name) เก็บค่าจาก Query ได้ 2 วิธี

วิธีที่ 1: SET ... = (SELECT ...)

CREATE TABLE DemoTable631 (
    StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    StudentName VARCHAR(100)
);

INSERT INTO DemoTable631(StudentName) VALUES
('John Smith'), ('Adam Smith'), ('David Miller');

SET @fullName = (SELECT StudentName FROM DemoTable631 WHERE StudentId = 2);

SELECT @fullName;  -- Adam Smith

วิธีที่ 2: SELECT ... INTO @variable

SELECT StudentName INTO @fullName 
FROM DemoTable631 
WHERE StudentId = 2;

ข้อแตกต่าง

คุณสมบัติSET @var = (SELECT)SELECT ... INTO @var
Return Rows > 1Error (Subquery returns > 1 row)Error (แต่ Warning ในบาง Version)
Return 0 Row@var = NULL@var ไม่เปลี่ยน (คงค่าเดิม)
Multiple Variablesไม่ได้ (SET เดียว 1 ตัว)ได้ (SELECT a,b INTO @x,@y)
ใช้ใน Stored Procedureได้ได้ (แนะนำ)

ตัวอย่าง Multiple Variables

SELECT StudentName, StudentId INTO @name, @id
FROM DemoTable631 WHERE StudentId = 1;

SELECT @name, @id;  -- John Smith, 1

Scope และ Lifetime

  • Session-scoped: ตัวแปร @var มีอยู่ต่อเนื่องใน Session/Connection เดียว
  • ไม่ร่วมกันระหว่าง Connection: Connection A ตั้ง @x = 1, Connection B มองไม่เห็น
  • หายเมื่อ Disconnect: ไม่ Persistent
  • Case Insensitive: @myVar = @myvar

กรณีใช้งานจริง

  1. Pass ค่าระหว่าง Statements:
    SET @last_id = LAST_INSERT_ID();
    INSERT INTO child_table (parent_id) VALUES (@last_id);
  2. Counter ใน Query:
    SELECT @rownum := @rownum + 1 AS row_number, name
    FROM users, (SELECT @rownum := 0) r;
  3. Dynamic SQL ใน Stored Procedure:
    SET @sql = CONCAT('SELECT * FROM ', @table_name);
    PREPARE stmt FROM @sql;
    EXECUTE stmt;

⚠️ ข้อควรระวัง

  • ไม่ควรใช้ใน WHERE Clause ของ Query เดียวที่ SET (Evaluation Order ไม่รับประกัน)
  • SET @x = 1; SELECT @x, @x := @x + 1; - Order ของ Evaluation ไม่กำหนด
  • ใน Replication: User Variables อาจไม่ Replicate ถูกต้อง (ใช้ Row-based Replication)