CodeGym /Các khóa học /SQL SELF /Cập nhật dữ liệu với UPDATE

Cập nhật dữ liệu với UPDATE

SQL SELF
Mức độ , Bài học
Có sẵn

Hôm nay tụi mình sẽ đến với một viên gạch quan trọng nữa trong kho kiến thức mới của bạn — cập nhật dữ liệu. Xem thử trong PostgreSQL làm sao để thay đổi thông tin đã có bằng lệnh UPDATE. Tại sao lại quan trọng? Vì ngoài đời dữ liệu không đứng yên đâu. Ví dụ bạn của bạn đổi số điện thoại, hay sinh viên chuyển sang nhóm khác — tất nhiên bạn sẽ muốn update lại trong database rồi.

Khi crush hồi cấp ba của bạn, Svetka Sokolova, bỗng thành Svetka Khachaturyan (vì đời mà), thì cũng phải sửa lại trong database thôi. Những tình huống cần update dữ liệu thì gặp hoài luôn:

  • Sửa lỗi trong bản ghi.
  • Cập nhật thông tin (chuyển nhà, đổi trạng thái).
  • Thay đổi hàng loạt, ví dụ tăng lương cho nhân viên.

Cập nhật dữ liệu là cách để đổi giá trị của một hoặc nhiều cột cho một hoặc nhiều dòng trong bảng, mà không cần thêm bản ghi mới.

Cú pháp lệnh UPDATE

Lệnh UPDATE trong PostgreSQL có cú pháp khá dễ hiểu. Xem cấu trúc nè:

UPDATE bảng
SET column1 = value1,
    column2 = value2
WHERE điều_kiện;

Giải thích:

  • bảng: tên bảng mà bạn muốn thay đổi gì đó.
  • SET column = value: tham số xác định cột nào cần đổi và giá trị mới là gì.
  • WHERE điều_kiện: điều kiện chỉ định dòng nào cần update (rất quan trọng để không update hết tất cả).

Điểm mấu chốt: nếu bạn quên thêm WHERE (hoặc viết sai), thay đổi của bạn sẽ áp dụng cho tất cả các dòng trong bảng. Thế là toang luôn đó.

Ví dụ: đổi tên sinh viên

Giả sử bạn có bảng students với các cột id, name, email. Bạn muốn đổi tên sinh viên có id = 1 thành "Maria Chi".

UPDATE students
SET name = 'Maria Chi'
WHERE id = 1;

Lệnh này sẽ tìm dòng có id = 1 và update cột name thành giá trị mới. Dễ mà đúng không?

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

Thường thì bạn sẽ muốn đổi nhiều giá trị trong một bản ghi. Ví dụ, sinh viên đổi không chỉ tên mà còn cả email. Làm như này nè:

UPDATE students
SET name = 'Otto Lin',
    email = 'otto.lin@example.com'
WHERE id = 2;

Ở đây mình update cả nameemail cho sinh viên có id = 2. PostgreSQL cho phép bạn ghi nhiều cặp cột=giá_trị cách nhau bằng dấu phẩy trong phần SET.

Cập nhật nhiều dòng

Làm sao nếu bạn muốn đổi dữ liệu cho nhiều dòng cùng lúc? Ví dụ, bạn muốn chuyển một nhóm sinh viên sang lớp mới. Có thể update các dòng thỏa mãn điều kiện nào đó. Giả sử có cột group_number, và bạn muốn chuyển tất cả sinh viên từ nhóm 101 sang nhóm 202:

UPDATE students
SET group_number = 202
WHERE group_number = 101;

Lệnh này sẽ update tất cả dòng mà group_number bằng 101, đổi thành 202.

5. Điều kiện WHERE: cẩn thận nha!

Như đã nói, WHERE là phao cứu sinh của bạn. Không có nó thì câu lệnh sẽ ảnh hưởng tới tất cả các dòng trong bảng. Ví dụ, lệnh sau sẽ update NHÓM của tất cả sinh viên, không chỉ nhóm 101. Đó là điều bạn chắc chắn không muốn đâu:

UPDATE students
SET group_number = 202;

Làm ơn, luôn luôn thêm WHERE nếu không muốn phá nát dữ liệu. Cẩn thận vẫn hơn.

Hãy nghĩ về lệnh UPDATE như lệnh đổi giá trị các cột trong bảng, chứ không phải dòng. Mục tiêu là gán giá trị mới cho tất cả ô của một cột nào đó. Và chỉ khi có WHERE thì mới không đổi hết mọi dòng.

Cập nhật dựa trên dữ liệu từ bảng khác

Đôi khi bạn không chỉ muốn "gõ" giá trị bằng tay, mà còn update giá trị trong bảng A dựa vào dữ liệu từ bảng B. Kiểu này gặp hoài — nhất là khi dữ liệu lưu riêng: ví dụ tính toán ở một bảng, còn profile user ở bảng khác.

Giả sử bạn có bảng students, cần update cột debt dựa vào bảng payments, nơi lưu số nợ hiện tại (due_amount). Mỗi bản ghi trong students sẽ có bản ghi tương ứng trong payments qua trường student_id.

Cú pháp sẽ như này:

UPDATE students
SET debt = payments.due_amount
FROM payments
WHERE students.id = payments.student_id;

Chuyện gì xảy ra:

  • PostgreSQL dùng FROM payments làm nguồn dữ liệu.
  • Điều kiện WHERE nối các dòng giữa hai bảng.
  • Chỉ update những dòng students có bản ghi tương ứng trong payments.

Quan trọng: trong UPDATE ... FROM thực ra là có một cái JOIN ngầm — JOIN, chỉ là không ghi từ khóa JOIN thôi.

Thực chất bên trong là JOIN ngầm. Thực tế nó kiểu như này:

UPDATE students
SET debt = p.due_amount
FROM payments p
    JOIN students s ON s.id = p.student_id
WHERE students.id = p.student_id;

Làm sao xem trước cái gì sẽ được update

Trước khi chạy UPDATE, rất nên xem thử cái gì sẽ bị đổi. Có thể dùng SELECT viết cùng nguyên tắc:

SELECT
    students.id, 
    students.name, 
    students.debt AS old_debt, 
    payments.due_amount AS new_debt
FROM students
    JOIN payments ON students.id = payments.student_id;

Kết quả sẽ cho thấy:

  • giá trị nợ cũ (old_debt);
  • giá trị mới sẽ lấy từ bảng payments (new_debt).

Cách này giúp bạn kiểm tra logic trước khi ghi đè dữ liệu mãi mãi.

Những bẫy tiềm ẩn

  • Nếu paymentsnhiều bản ghi cho một sinh viên, UPDATE sẽ báo lỗi: more than one row returned. Bạn phải dùng hàm tổng hợp (MAX, SUM, LIMIT 1), hoặc đảm bảo student_id trong payments là duy nhất.
  • Đừng quên, UPDATE ... FROM là đặc sản của PostgreSQL, không chạy được kiểu này ở vài hệ quản trị khác (ví dụ MySQL).

Ví dụ thực tế

Ví dụ 1: Đổi trạng thái sinh viên

Giả sử sinh viên hoàn thành khóa học sẽ có trạng thái "tốt nghiệp". Có cột status. Để update trạng thái cho sinh viên có completed_course = true:

UPDATE students
SET status = 'tốt nghiệp'
WHERE completed_course = true;

Ví dụ 2: Tăng lương cho nhân viên

Nếu bạn có bảng employees, muốn tăng lương 10% cho tất cả ai làm ở phòng Sales:

UPDATE employees
SET salary = salary * 1.10
WHERE department = 'Sales';

Ở đây mình dùng phép toán ngay trong phần SET. Rất tiện cho thay đổi hàng loạt.

Ví dụ 3: Update có điều kiện

Đôi khi cần update dữ liệu tùy theo điều kiện. Ví dụ, nếu lương nhân viên dưới 50,000 thì tăng 20%, còn trên thì tăng 10%:

UPDATE employees
SET salary = CASE
                WHEN salary < 50000 THEN salary * 1.20
                ELSE salary * 1.10
             END;

Lệnh này dùng cấu trúc CASE để đặt quy tắc update khác nhau tùy giá trị salary.

Lỗi thường gặp khi dùng UPDATE

Chắc bạn cũng đoán ra lỗi phổ biến nhất là gì rồi nhỉ? Đúng rồi, quên WHERE. Thử tưởng tượng: bạn có database 10,000 nhân viên, mà lỡ tăng lương cho tất cả. Nhân viên thì vui, nhưng sự nghiệp của bạn thì... hơi căng.

Một lỗi nữa là update nhầm cột. Luôn kiểm tra kỹ bạn đang ghi gì vào đâu. Một câu SELECT trước UPDATE có thể cứu bạn cả đống thời gian đó.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION