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

Chèn giá trị có số 0 dẫn đầu (LPAD) vào MySQL với INSERT INTO SELECT

Vấn đề: Tự động sinh UserId dạng '001', '002'... khi chèn hàng mới

Cần UserId VARCHAR(20) có 3 chữ số, điền 0 đầu, tự động tăng dựa trên MAX(Id) hiện có.

Giải pháp: INSERT INTO SELECT + LPAD + COALESCE

1. Tạo bảng

CREATE TABLE DemoTable (
    Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    UserId VARCHAR(20)
);

2. Chèn hàng đầu tiên (bảng rỗng)

INSERT INTO DemoTable (UserId)
SELECT LPAD(COALESCE(MAX(Id), 0) + 1, 3, '0') FROM DemoTable;

3. Lặp lại 2 lần nữa

INSERT INTO DemoTable (UserId)
SELECT LPAD(COALESCE(MAX(Id), 0) + 1, 3, '0') FROM DemoTable;

INSERT INTO DemoTable (UserId)
SELECT LPAD(COALESCE(MAX(Id), 0) + 1, 3, '0') FROM DemoTable;

4. Kết quả

+----+--------+
| Id | UserId |
+----+--------+
|  1 | 001    |
|  2 | 002    |
|  3 | 003    |
+----+--------+

Giải thích

  • MAX(Id) – Lấy ID lớn nhất hiện có (kiểu INT).
  • COALESCE(MAX(Id), 0) – Nếu bảng rỗng, MAX trả NULL → COALESCE chuyển thành 0.
  • + 1 – Số thứ tự tiếp theo.
  • LPAD(..., 3, '0') – Đệm trái chuỗi '0' để đủ 3 ký tự.

Cảnh báo: Race Condition (Điều kiện đua)

Cách này KHÔNG AN TOÀN cho môi trường đa người dùng (concurrent inserts). Hai session cùng đọc MAX(Id) = 3, cùng chèn '004' → trùng UserId.

Giải pháp an toàn

  • Dùng cột Id INT AUTO_INCREMENT làm khóa chính thực sự.
  • Tạo UserId là GENERATED ALWAYS AS (LPAD(Id, 3, '0')) STORED (MySQL 5.7+).
  • Hoặc dùng SEQUENCE (MariaDB 10.3+, MySQL 8.0 không có sequence chuẩn).