Học bằng cách đọc theo thứ tự

UPDATE và DELETE — Cập nhật và xóa hàng

Học SQL UPDATE và DELETE từ cơ bản. Bao gồm cập nhật nhiều cột với SET, xóa thu hẹp với WHERE, và điều gì xảy ra khi bạn quên WHERE — tất cả chạy trực tiếp trên trình duyệt của bạn.

UPDATE — viết lại các hàng hiện có

INSERT là để "thêm hàng mới." UPDATE là thao tác để viết lại các giá trị của hàng đã tồn tại. Thay đổi trạng thái thành viên, sửa giá sản phẩm, cập nhật số lần mua — UPDATE là phần của hoạt động hằng ngày trong bất kỳ ứng dụng chính thức nào.

Dạng cơ bản là UPDATE table_name SET col = val WHERE condition;. SET nói "cột nào nhận giá trị nào," và WHERE nói "hàng nào bị ảnh hưởng."

-- Viết lại status của customer nơi id = 1 thành 'active'
UPDATE customer SET status = 'active' WHERE id = 1;

-- Kiểm tra kết quả
SELECT * FROM customer;
Cấu trúc của câu lệnh UPDATE
UPDATE tableSET col = valWHERE conditionBảng đíchcustomerThay đổistatus = 'active'Hàng đíchid = 1Bảng đíchViết lại cộtThu hẹp hàng
UPDATE table_name là bảng đích, SET col = val là thay đổi, và WHERE condition thu hẹp xuống các hàng nào. Hãy nắm vị trí và vai trò của từng phần.

Quên WHERE cập nhật mọi hàng

Bỏ WHERE khỏi UPDATE customer SET status = 'active' WHERE id = 1; (trở thành UPDATE customer SET status = 'active';) và mọi hàng của customerstatus của nó được viết lại thành 'active'. Không có lỗi, đó chính là điều khiến đây là cách dễ làm hỏng dữ liệu production một cách âm thầm.

Hãy hình dung chuyển một khách hàng (Alice) từ pending sang active. (Chạy đúng thì phần giải thích sẽ hiện ra.)

① Đầu tiên chạy SELECT name, status FROM customer WHERE id = 1; và xác nhận status của Alice là 'pending' (chưa active).

② Cập nhật cột status thành 'active' cho hàng trong customer nơi `id = 1` (Alice).

③ Cuối cùng, chạy SELECT * FROM customer; và xác nhận chỉ status của Alice đã đổi thành 'active', trong khi Bob và Carol không đổi.

(WHERE ở đây dùng cùng cú pháp lọc bạn đã thấy trong bài SELECT.)

SQL Editor

Chạy truy vấn để xem kết quả

Cập nhật nhiều cột cùng lúc

Bằng cách liệt kê các cặp `col = val` ngăn cách bằng dấu phẩy trong mệnh đề SET, bạn có thể cập nhật nhiều cột cùng lúc: SET col1 = val1, col2 = val2, ....

Vế phải cũng có thể là một biểu thức bao gồm chính cột đó. SET price = price + 100 nghĩa là "viết lại price của hàng đích thành price hiện tại cộng 100."

Các biến thể của mệnh đề SET
Một cột đơnSET status = 'active'Nhiều cột(ngăn cách bằng dấu phẩy)SET price = 200, stock = 100Biểu thức(tham chiếu chính nó)SET price = price + 100Kết hợpSET price = price + 100, stock = stock - 10
SET có thể chứa một cặp col = val đơn hoặc nhiều cặp ngăn cách bằng dấu phẩy, và vế phải cũng có thể là một biểu thức.
-- Cập nhật nhiều cột thành giá trị tuyệt đối cùng lúc
UPDATE inventory SET price = 200, stock = 100 WHERE id = 2;

-- Cập nhật bằng biểu thức (tham chiếu giá trị hiện có)
UPDATE inventory SET price = price + 100, stock = stock - 10 WHERE id = 2;

Hãy hình dung một màn hình kho nơi bạn muốn sửa giá và số lượng tồn của tẩy.

① Cho hàng trong inventory nơi `id = 2` (Tẩy), cập nhật price thành 200stock thành 100 cùng lúc.

② Cuối cùng, chạy SELECT * FROM inventory; và xác nhận chỉ id=2 được cập nhật với giá trị mới, trong khi id=1 (Bút chì) và id=3 (Vở) không đổi.

SQL Editor

Chạy truy vấn để xem kết quả

Hãy hình dung: "tăng giá bút chì (id=1) lên 100 và giảm tồn kho 10." Đặt một biểu thức tham chiếu chính cột ở vế phải của SET cho phép bạn thực hiện thay đổi tương đối với giá trị hiện tại.

① Cho hàng trong inventory nơi `id = 1` (Bút chì), cập nhật cả hai cột cùng lúc với `price = price + 100``stock = stock - 10`.

② Cuối cùng, chạy SELECT * FROM inventory WHERE id = 1; và xác nhận price của bút chì là 180 và stock là 190.

SQL Editor

Chạy truy vấn để xem kết quả

DELETE — xóa hàng

DELETE là thao tác để xóa hàng khỏi bảng. Dạng cơ bản là DELETE FROM table_name WHERE condition;, với WHERE thu hẹp xuống các hàng đích. Khác với SELECT, không có danh sách cột (SELECT col1, col2) — DELETE xóa toàn bộ hàng.

Định nghĩa bảng (cấu trúc cột) vẫn còn, nên bạn có thể INSERT vào cùng bảng sau khi xóa. Để xóa chính bảng, dùng DROP TABLE / TRUNCATE (đề cập trong bài tiếp theo).

Cấu trúc của câu lệnh DELETE
DELETE FROM tableWHERE conditionBảng đíchsubscriptionHàng cần xóastatus = 'expired'Bảng đíchThu hẹp hàng
DELETE FROM table_name là bảng đích; WHERE condition quyết định hàng nào để xóa. Không có tương đương với danh sách cột của SELECT hay mệnh đề SET của UPDATE trong DELETE.
-- Xóa tất cả các đăng ký đã hết hạn (status = 'expired')
DELETE FROM subscription WHERE status = 'expired';

-- Kiểm tra kết quả (chỉ các hàng còn sống)
SELECT * FROM subscription;

Hãy hình dung dọn dẹp các đăng ký đã hết hạn hàng loạt.

① Từ subscription, xóa mọi hàng có `status` là `'expired'`.

② Cuối cùng, chạy SELECT * FROM subscription; và xác nhận các sống sót duy nhất là 2 hàng có status = 'active' (Bob / Dave).

(Mọi hàng khớp điều kiện WHERE đều là đích — không cần chỉ định id, nhiều hàng khớp biến mất cùng lúc.)

SQL Editor

Chạy truy vấn để xem kết quả

Coi chừng quên WHERE — bẫy cập nhật/xóa mọi hàng

Quên WHERE là tai nạn phổ biến nhất với UPDATE và DELETE. Không có WHERE, cú pháp vẫn hợp lệ — và đích mở rộng đến mọi hàng trong bảng. UPDATE table SET col = val; viết lại mọi hàng thành cùng giá trị; DELETE FROM table; làm trống bảng.

Ngay cả khi bạn nhận ra ngay, bạn không thể hoàn tác sau khi thay đổi đã commit. Quy tắc vận hành cơ bản trong production là luôn chạy cùng WHERE như một `SELECT` trước để xác nhận trực quan các hàng đích trước khi viết lại.

Có WHERE vs. không có WHERE
DELETE FROM cache_entry WHERE id = 1;→ Chỉ xóa id=1(an toàn — thu hẹp bằng WHERE)DELETE FROM cache_entry;→ Mọi hàng bị xóa(bảng trở nên trống)UPDATE customer SET status = 'active' WHERE id = 1;→ Chỉ cập nhật id=1(các customer khác không đổi)UPDATE customer SET status = 'active';→ status mọi hàng đặt thành 'active'(mọi customer trở nên active)
Chỉ cần có hoặc không có WHERE thay đổi thao tác giữa "tác động lên một hàng được nhắm" và "tác động lên mọi hàng cùng lúc." Phạm vi tác động của việc quên là, theo nghĩa đen, toàn bộ bảng.

Trong production, xác nhận hàng đích bằng SELECT trước

Đối với UPDATE / DELETE trên cơ sở dữ liệu production, chạy cùng WHERE như một SELECT trước và xác nhận trực quan các hàng đích đúng như mong đợi trước khi chuyển sang viết lại. Quy trình hai bước:

1. Chạy SELECT * FROM table_name WHERE condition; để xác nhận hàng đích (số hàng và giá trị có khớp những gì bạn mong đợi không?)

2. Nếu mọi thứ đúng, chuyển cùng WHERE sang UPDATE table_name SET col = val WHERE condition; hoặc DELETE FROM table_name WHERE condition; và thực thi

Vì mệnh đề WHERE được dùng lại qua sao chép-dán, điều này cũng giảm loại tai nạn nơi WHERE bị bỏ vô tình trong khi viết lại.

Hãy hình dung: "xóa cache và xây dựng lại từ đầu." Bảng cache_entry bắt đầu bài viết với 3 hàng cache trong đó.

Không viết WHERE, chạy một DELETE xóa mọi hàng của cache_entry.

② Cuối cùng, chạy SELECT * FROM cache_entry; và xác nhận kết quả là 0 hàng (bảng trống).

(DELETE không có WHERE là công thức cho tai nạn trong production — ở đây nó được cố ý đặt làm bài tập cuối để bạn cảm nhận hành vi của nó.)

SQL Editor

Chạy truy vấn để xem kết quả
QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Câu nào mô tả đúng vai trò của SETWHERE trong câu lệnh UPDATE?

Câu 2Cách đúng để cập nhật cả nameemail cho hàng trong customer nơi id = 1 cùng lúc là gì?

Câu 3Điều gì xảy ra khi bạn chạy DELETE FROM product; không có WHERE?