Hướng Dẫn Chi Tiết Cách Sử Dụng Trigger Trong SQL Server Với Ví Dụ Thực Tế

Trigger trong SQL Server là một công cụ mạnh mẽ giúp tự động thực thi các đoạn mã SQL khi có sự kiện xảy ra trên một bảng cụ thể. Bài viết này sẽ cung cấp hướng dẫn chi tiết cách sử dụng Trigger thông qua các ví dụ thực tế trên database quản lý bán hàng (QuanLyBanHang), giúp bạn hiểu rõ và áp dụng hiệu quả vào các dự án của mình.

Database QuanLyBanHang bao gồm 9 bảng: NHACC, VATTU, DONDH, CTDONDH, PNHAP, CTPNHAP, PXUAT, CTPXUAT và TONKHO.

Tổng Quan Về Trigger Trong SQL Server

Trigger là một loại stored procedure đặc biệt, tự động kích hoạt khi có sự kiện INSERT, UPDATE hoặc DELETE xảy ra trên một bảng. Trigger được sử dụng để duy trì tính toàn vẹn dữ liệu, kiểm soát các thao tác trên dữ liệu và thực hiện các tác vụ phức tạp khác.

Database Diagram Quản Lý Bán HàngDatabase Diagram Quản Lý Bán Hàng

Các Loại Trigger Phổ Biến

Có hai loại trigger chính trong SQL Server:

  • AFTER Trigger: Kích hoạt sau khi sự kiện (INSERT, UPDATE, DELETE) đã xảy ra.
  • INSTEAD OF Trigger: Thay thế sự kiện ban đầu.

Trong bài viết này, chúng ta sẽ tập trung vào AFTER Trigger.

Các Ví Dụ Về Trigger Trong Quản Lý Bán Hàng

Dưới đây là 3 ví dụ cụ thể về cách sử dụng trigger trong database QuanLyBanHang:

Câu 1: Tạo trigger khi update hoặc insert cột SLNhap của bảng CTPNHAP thì tổng số lượng nhập phải nhỏ hơn hoặc bằng tổng số lượng đặt của bảng CTDONDH.

Câu 2: Tạo trigger khi update cột SLNhap của bảng CTPNHAP thì cột TongSLN (Tổng số lượng nhập) của bảng TONKHO được cập nhật theo.

Câu 3: Tạo trigger khi update hoặc insert dữ liệu của bảng TONKHO, cột SLCuoi (Số lượng cuối) được tính theo công thức SLCuoi = SLDau + TongSLN – TongSLX.

Hướng Dẫn Thực Hiện Chi Tiết

Câu 1: Kiểm Tra Số Lượng Nhập So Với Số Lượng Đặt

Giải thích: Trigger này đảm bảo rằng tổng số lượng nhập của một vật tư không vượt quá tổng số lượng đã đặt cho vật tư đó. Điều này giúp ngăn chặn tình trạng nhập hàng vượt quá nhu cầu thực tế.

Câu lệnh tạo trigger:

CREATE TRIGGER TRG_CTPNHAP_SLNhap
ON CTPNHAP
AFTER INSERT, UPDATE
AS
BEGIN
    -- Kiểm tra tổng số lượng nhập có vượt quá số lượng đặt hay không
    IF EXISTS (
        SELECT 1
        FROM CTPNHAP ct
        JOIN CTDONDH dh ON ct.SoDh = dh.SoDh AND ct.MaVTU = dh.MaVTU
        WHERE ct.SLNhap > dh.SLDat
    )
    BEGIN
        -- Nếu vượt quá, hủy thao tác và thông báo lỗi
        RAISERROR('Tổng số lượng nhập không được vượt quá số lượng đặt.', 16, 1)
        ROLLBACK TRANSACTION
    END
END

Câu lệnh tạo trigger kiểm tra số lượng nhậpCâu lệnh tạo trigger kiểm tra số lượng nhập

Giải thích câu lệnh:

  • CREATE TRIGGER TRG_CTPNHAP_SLNhap: Tạo một trigger với tên là TRG_CTPNHAP_SLNhap.
  • ON CTPNHAP: Trigger này được kích hoạt trên bảng CTPNHAP.
  • AFTER INSERT, UPDATE: Trigger này được kích hoạt sau khi có thao tác INSERT hoặc UPDATE trên bảng CTPNHAP.
  • IF EXISTS (...): Kiểm tra xem có tồn tại bản ghi nào mà số lượng nhập (SLNhap) lớn hơn số lượng đặt (SLDat) hay không.
  • RAISERROR(...): Nếu điều kiện trên đúng, hiển thị thông báo lỗi.
  • ROLLBACK TRANSACTION: Hủy bỏ giao dịch hiện tại, ngăn không cho dữ liệu được thay đổi.

Trigger sau khi tạo thành công:

Trigger CTPNHAP_SLNhap đã được tạo thành côngTrigger CTPNHAP_SLNhap đã được tạo thành công

Câu 2: Cập Nhật Tổng Số Lượng Nhập Trong Bảng TONKHO

Giải thích: Khi số lượng nhập của một vật tư thay đổi trong bảng CTPNHAP, trigger này sẽ tự động cập nhật tổng số lượng nhập (TongSLN) tương ứng trong bảng TONKHO. Điều này giúp đảm bảo tính nhất quán của dữ liệu giữa hai bảng.

Câu lệnh tạo trigger:

CREATE TRIGGER TRG_CTPNHAP_SLNhap_Update_TONKHO
ON CTPNHAP
AFTER UPDATE
AS
BEGIN
    -- Cập nhật tổng số lượng nhập trong bảng TONKHO
    UPDATE TONKHO
    SET TongSLN = (
        SELECT SUM(ct.SLNhap)
        FROM CTPNHAP ct
        JOIN PNHAP pn ON ct.SoPN = pn.SoPN
        WHERE TONKHO.MaVTU = ct.MaVTU
          AND YEAR(pn.NgayNhap) = YEAR(GETDATE())
          AND MONTH(pn.NgayNhap) = MONTH(GETDATE())
    )
    WHERE EXISTS (SELECT 1 FROM inserted WHERE inserted.MaVTU = TONKHO.MaVTU);
END

Câu lệnh tạo trigger cập nhật tổng số lượng nhậpCâu lệnh tạo trigger cập nhật tổng số lượng nhập

Giải thích câu lệnh:

  • CREATE TRIGGER TRG_CTPNHAP_SLNhap_Update_TONKHO: Tạo một trigger với tên là TRG_CTPNHAP_SLNhap_Update_TONKHO.
  • ON CTPNHAP: Trigger này được kích hoạt trên bảng CTPNHAP.
  • AFTER UPDATE: Trigger này được kích hoạt sau khi có thao tác UPDATE trên bảng CTPNHAP.
  • UPDATE TONKHO ...: Cập nhật cột TongSLN trong bảng TONKHO.
  • (SELECT SUM(ct.SLNhap) ...): Tính tổng số lượng nhập của vật tư từ bảng CTPNHAPPNHAP dựa trên điều kiện năm và tháng nhập hàng.
  • WHERE EXISTS (SELECT 1 FROM inserted WHERE inserted.MaVTU = TONKHO.MaVTU): Đảm bảo rằng chỉ cập nhật những bản ghi trong TONKHO mà có mã vật tư (MaVTU) tồn tại trong bản ghi vừa được cập nhật (inserted) ở bảng CTPNHAP.

Câu 3: Tính Toán Số Lượng Cuối Trong Bảng TONKHO

Giải thích: Trigger này tự động tính toán số lượng cuối (SLCuoi) trong bảng TONKHO dựa trên số lượng đầu (SLDau), tổng số lượng nhập (TongSLN) và tổng số lượng xuất (TongSLX). Việc này giúp đảm bảo tính chính xác của thông tin tồn kho.

Câu lệnh tạo trigger:

CREATE TRIGGER TRG_TONKHO_Update_SLCuoi
ON TONKHO
AFTER INSERT, UPDATE
AS
BEGIN
    -- Cập nhật số lượng cuối (SLCuoi)
    UPDATE TONKHO
    SET SLCuoi = SLDau + TongSLN - TongSLX
    WHERE EXISTS (SELECT 1 FROM inserted WHERE inserted.MaVTU = TONKHO.MaVTU);
END

Kiểm Tra Hoạt Động Của Trigger

Để đảm bảo các trigger hoạt động đúng như mong đợi, chúng ta cần thực hiện các kiểm tra sau:

Kiểm Tra Trigger 1: Ngăn Chặn Nhập Vượt Quá Số Lượng Đặt

Số lượng đặt của vật tư DD01 là 18:

Số lượng đặt của vật tư DD01 là 18Số lượng đặt của vật tư DD01 là 18

Tổng số lượng nhập của vật tư DD01 là 13, không vượt quá số lượng đặt là 18:

Tổng số lượng nhập của vật tư DD01 là 13Tổng số lượng nhập của vật tư DD01 là 13

Khi thay đổi số lượng nhập của vật tư DD01 từ 5 thành 15, tổng số lượng nhập lúc này là 23. Do đó, tổng số lượng nhập cao hơn số lượng đặt trong bảng CTDONDH (23 > 18).

Thay đổi số lượng nhập của vật tư DD01Thay đổi số lượng nhập của vật tư DD01

Trigger ngăn chặn không cho thay đổi số lượng nhập:

Trigger ngăn chặn thay đổi số lượng nhậpTrigger ngăn chặn thay đổi số lượng nhập

Kiểm Tra Trigger 2: Cập Nhật Tổng Số Lượng Nhập Trong Bảng TONKHO

Khi chúng ta thay đổi số lượng nhập (SlNhap) của dòng 1 hoặc dòng 2 thì tổng số lượng nhập sẽ là 10. Mặc dù, dòng 3 cũng là vật tư DD02 nhưng số lượng nhập không được tính:

Thay đổi số lượng nhập của vật tư DD02Thay đổi số lượng nhập của vật tư DD02

Dựa vào số phiếu nhập (SoPn) chúng ta biết được ngày nhập (NgayNhap). Và chúng ta dễ dàng nhận thấy chỉ có N001 và N002 có cùng tháng và cùng năm nhập là 01/2007.

Phiếu nhập và ngày nhậpPhiếu nhập và ngày nhập

Tại bảng TONKHO, mặc dù có 2 dòng cùng chứa vật tư (MaVTu) là DD02 nhưng chỉ có tổng số lượng nhập (TongSLN) của dòng 1 được cập nhật vì đúng năm tháng là 200701.

Bảng TONKHO sau khi cập nhậtBảng TONKHO sau khi cập nhật

Kết Luận

Sử dụng Trigger trong SQL Server là một cách hiệu quả để duy trì tính toàn vẹn dữ liệu và tự động hóa các tác vụ trong cơ sở dữ liệu. Bằng cách áp dụng các ví dụ và hướng dẫn trong bài viết này, bạn có thể xây dựng các trigger mạnh mẽ để quản lý dữ liệu trong hệ thống của mình một cách hiệu quả hơn. Hãy nhớ kiểm tra kỹ lưỡng các trigger sau khi tạo để đảm bảo chúng hoạt động đúng như mong đợi.