Day 14 - Pro: Stored Procedures, Transactions & User-Defined Functions
Bối cảnh: Hệ thống E-commerce (Thương mại điện tử) - Tương tự Shopee
1. User-defined functions
User-defined functions (UDFs): Cho phép tạo các hàm tùy chỉnh để thực hiện các tính toán phức tạp hoặc lặp đi lặp lại.
Ví dụ: Tạo hàm tính tổng giá trị đơn hàng sau khi áp dụng thuế:
CREATE FUNCTION calculate_total_with_tax(total_amount DECIMAL, tax_rate DECIMAL) RETURNS DECIMAL AS $$ BEGIN RETURN total_amount * (1 + tax_rate); END; $$ LANGUAGE plpgsql;
Sử dụng hàm:
SELECT order_id, total_amount, calculate_total_with_tax(total_amount, 0.1) AS total_with_tax FROM orders;
2. User-defined functions - Example
Ví dụ khác: Tạo hàm để kiểm tra xem một sản phẩm có thuộc danh mục "Electronics" hay không:
CREATE FUNCTION is_electronics(category VARCHAR) RETURNS BOOLEAN AS $$ BEGIN RETURN category = 'Electronics'; END; $$ LANGUAGE plpgsql;
Sử dụng hàm:
SELECT product_name, is_electronics(category) AS is_electronics FROM products;
3. Challenge: User-defined functions
- Yêu cầu: Tạo hàm để tính tổng số lượng sản phẩm đã bán của một khách hàng cụ thể (customer_id).
4. Solution: User-defined functions
Giải pháp:
CREATE FUNCTION total_quantity_sold(customer_id INT) RETURNS INT AS $$ BEGIN RETURN (SELECT SUM(quantity) FROM orders WHERE orders.customer_id = total_quantity_sold.customer_id); END; $$ LANGUAGE plpgsql;
Sử dụng hàm:
SELECT customer_name, total_quantity_sold(customer_id) AS total_quantity FROM customers;
5. Transactions
Transactions: Một nhóm các câu lệnh SQL được thực hiện như một đơn vị công việc duy nhất.
ACID Properties:
Atomicity: Tất cả các thao tác trong transaction phải thành công hoặc không có gì xảy ra.
Consistency: Dữ liệu phải ở trạng thái hợp lệ trước và sau transaction.
Isolation: Các transaction độc lập với nhau.
Durability: Kết quả của transaction phải được lưu trữ vĩnh viễn.
Ví dụ:
BEGIN; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; COMMIT;
6. Challenge: Transactions
- Yêu cầu: Tạo transaction để cập nhật số lượng sản phẩm trong kho (inventory) sau khi đặt hàng.
7. Solution: Transactions
Giải pháp:
BEGIN; UPDATE inventory SET quantity = quantity - 1 WHERE product_id = 101; INSERT INTO orders (order_id, customer_id, product_id, quantity, total_amount, order_date) VALUES (1001, 1, 101, 1, 50.00, NOW()); COMMIT;
8. Rollbacks
Rollback: Hủy bỏ các thay đổi trong transaction nếu có lỗi xảy ra.
Ví dụ:
BEGIN; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; ROLLBACK;
9. Stored procedures
Stored Procedures: Một nhóm các câu lệnh SQL được lưu trữ trong database và có thể được gọi lại nhiều lần.
Ví dụ: Tạo stored procedure để thêm một đơn hàng mới:
CREATE PROCEDURE add_order( IN p_order_id INT, IN p_customer_id INT, IN p_product_id INT, IN p_quantity INT, IN p_total_amount DECIMAL, IN p_order_date DATE ) AS $$ BEGIN INSERT INTO orders (order_id, customer_id, product_id, quantity, total_amount, order_date) VALUES (p_order_id, p_customer_id, p_product_id, p_quantity, p_total_amount, p_order_date); END; $$ LANGUAGE plpgsql;
Gọi stored procedure:
CALL add_order(1002, 2, 102, 2, 100.00, NOW());
10. Challenge: Stored procedures
- Yêu cầu: Tạo stored procedure để cập nhật giá của một sản phẩm (product_id) và ghi lại lịch sử thay đổi giá.
11. Solution: Stored procedures
Giải pháp:
CREATE PROCEDURE update_product_price( IN p_product_id INT, IN p_new_price DECIMAL ) AS $$ BEGIN -- Lưu giá cũ vào bảng lịch sử INSERT INTO price_history (product_id, old_price, new_price, change_date) SELECT product_id, price, p_new_price, NOW() FROM products WHERE product_id = p_product_id; -- Cập nhật giá mới UPDATE products SET price = p_new_price WHERE product_id = p_product_id; END; $$ LANGUAGE plpgsql;
Gọi stored procedure:
CALL update_product_price(101, 55.00);
12. Today's slides
Tổng kết lại các kiến thức về User-defined functions, Transactions, và Stored Procedures.
Slide tham khảo cung cấp ví dụ chi tiết và ứng dụng trong hệ thống E-commerce.
13. Today's summary
Hôm nay, bạn đã học:
Cách tạo và sử dụng User-defined functions để thực hiện các tính toán tùy chỉnh.
Cách quản lý Transactions để đảm bảo tính toàn vẹn dữ liệu.
Cách tạo và gọi Stored Procedures để tự động hóa các tác vụ phức tạp.
Hẹn gặp lại bạn vào ngày 15 với chủ đề Pro: Indexes, Partitioning & Query Optimization!
14. Today's challenges
Thử thách 1: Tạo hàm để tính tổng doanh thu của một khách hàng (customer_id) trong một khoảng thời gian cụ thể.
Thử thách 2: Tạo transaction để cập nhật số lượng sản phẩm trong kho (inventory) và thêm đơn hàng mới.
Thử thách 3: Tạo stored procedure để xóa một sản phẩm (product_id) và ghi lại lịch sử xóa.