Home > SQL > Sử dụng COLUMNS_UPDATED() để kiểm tra trường được update trong trigger

Sử dụng COLUMNS_UPDATED() để kiểm tra trường được update trong trigger

1. ĐẶT VẤN ĐỀ

Có khách hàng làm về ô tô, có cái bảng dữ liệu SECTROPT lưu thông tin chi tiết phụ tùng được xuất ra để sửa chữa xe. Sau khi sửa xong thì kế toán xuất hóa đơn. 1 Hóa đơn (thông tin hóa đơn được lưu trong bảng PH51) có thể xuất được cho nhiều dòng trong SECTROPT vì thế thiết kế dữ liệu trong bảng SECTROPT phải lưu lại khóa của hóa đơn (đặt tên trường là Stt_rechd, khóa của  bảng PH51 là Stt_rec).

Để đáp ứng nhu cầu truy vấn nhanh hơn thì lưu thêm cái So_hd vào bảng SECTROPT nữa (nếu không cứ mỗi khi cần truy vấn số hóa đơn lại phải JOIN với PH51 thì mất công lắm).

Vấn đề đặt ra là:

  • sau khi lưu thông tin hóa đơn xong thì Stt_rechd và so_hd đã được lưu vào SECTROPT.
  • Khi User sửa số hóa đơn thì chương trình phải update lại trường so_hd trong bảng SECTROPT. => viết trigger UPDATE cho PH51 là OK.
  • Tuy nhiên, So_hd thì ít khi sửa (chủ yếu sửa mấy cái diễn giải) nên không lẽ cứ mỗi lần sửa – lưu thì trigger lại phải chạy?

Nói chung vào đề hơi dài dòng. Nói tóm lại là sau một hồi Research (cái này từ năm 2007 rồi, hôm nay nhớ ra mới viết) thì sử dụng hàm COLUMNS_UPDATED() để kiểm tra xem trường nào được update, nếu trường đó là So_hd thì mới thực thi update vào SECTROPT.

2. Về COLUMNS_UPDATED()

Chi tiết thì có thể hỏi “anh Hai google”, ở đây xin giới thiệu cái cơ bản của hàm COLUMNS_UPDATED() thôi.

Đại khái, hàm này sẽ trả về giá trị dạng nhị phân có ý nghĩa, chỉ ra vị trí cột nào được insert hoặc update

Để kiểm tra cột nào được thay đổi mình sử dụng bit mặt nạ tương ứng cho vị trí của mỗi cột.

 

Để kiểm tra các cột có vị trí <=8

Cột tại vị trí n (n<=8) có phải là cột thay đổi hay không thì sử dụng biểu thức sau:

COLUMNS_UPDATED() & Power(2,(n-1))

Nếu biểu thức đó >0 thì cột n đã thay đổi, ngược lại cột n không thay đổi.

Trong trường hợp kiểm tra 2 hoặc nhiều cột có thay đổi hay không thì làm tương tự. Ví dụ kiểm tra cột 3 cột i,j,k có thay đổi hay không (i,j,k<=8) thì sử dụng biểu thức sau:

COLUMNS_UPDATED() & (Power(2,(i-1)) + Power(2,(j-1)) + Power(2,(k-1)))

Chú ý: Để đỡ phải tính toán khi thực thi thì mình tính ra giá trị nguyên của các hàm Power() luôn rồi cho COLUMNS_UPDATED() & kq (là giá trị của biểu thức sau &)

 

Để kiểm tra các cột có vị trí >8

Sử dụng hàm SUBSTRING() cho giá trị trả về của COLUMNS_UPDATED().

Ví dụ cần kiểm tra có update cột 10 hay không, sử dụng biểu thức sau:

SUBSTRING(COLUMNS_UPDATED(),2,1) & Power(2,(10-8-1))

Còn nếu cột cần kiểm tra > 16 thì làm tương tự. Ví dụ cần kiểm tra cột 19 có Update không thì sử dụng biểu thức:

SUBSTRING(COLUMNS_UPDATED(),3,1) & Power(2,(19-16-1))

3. TRIGGER

Còn đây là trigger cho đề bài ở trên.

CREATE TRIGGER [dbo].[TG_UpdatePh51]
ON [dbo].[ph51]
AFTER UPDATE
AS

IF SUBSTRING(COLUMNS_UPDATED(),2,1) & 4> 0 –- Cột So_hd là cột thứ 11; power(2,(11-8-1)) =4
BEGIN
    declare @So_hd varchar(8), @stt_rechd varchar(20)
    SELECT @So_hd = So_hd, @stt_recOld = Stt_rec from inserted

    UPDATE SECTROPT
    SET So_hd = @So_hd
    WHERE Stt_rechd  = @stt_rechd
END

Advertisements
Categories: SQL
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: