Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

TSQL:lỗi được chỉ định loại không boolean khi sử dụng cập nhật trong trình kích hoạt

Nếu bạn chỉ muốn ghi lại các thay đổi của các cột riêng lẻ trong trình kích hoạt của mình, bạn có thể thử hủy chia sẻ, có thể kết hợp với kết hợp đầy đủ. Ý tưởng là, bạn bỏ chia cả hai inserteddeleted sau đó nối chúng trên khóa của bảng và cột chứa các tên chưa được phân chia, lọc ra các hàng có giá trị giống nhau.

Đây là một ví dụ minh họa về phương pháp này.

Đầu tiên, các định nghĩa bảng:

CREATE TABLE TestTable (
  ID int IDENTITY PRIMARY KEY,
  Attr1 int,
  Attr2 int,
  Attr3 int
);

CREATE TABLE TestTableLog (
  ID int IDENTITY PRIMARY KEY,
  TableID int,
  AttrName sysname,
  OldValue int,
  NewValue int,
  Timestamp datetime DEFAULT GETDATE()
);

Tiếp theo, một trình kích hoạt để ghi nhật ký thay đổi. Cái này sẽ bắt tất cả các thao tác:chèn, cập nhật và xóa:

CREATE TRIGGER trTestTable ON TestTable
AFTER INSERT, UPDATE, DELETE
AS BEGIN
  WITH inserted_unpivot AS (
    SELECT
      ID,
      AttrName,
      Value
    FROM inserted i
    UNPIVOT (Value FOR AttrName IN (Attr1, Attr2, Attr3)) u
  ),
  deleted_unpivot AS (
    SELECT
      ID,
      AttrName,
      Value
    FROM deleted d
    UNPIVOT (Value FOR AttrName IN (Attr1, Attr2, Attr3)) u
  )
  INSERT INTO TestTableLog (TableID, AttrName, OldValue, NewValue)
  SELECT
    ISNULL(i.ID, d.ID),
    ISNULL(i.AttrName, d.AttrName),
    d.Value,
    i.Value
  FROM inserted_unpivot i
    FULL JOIN deleted_unpivot d
      ON i.ID = d.ID AND i.AttrName = d.AttrName
  WHERE CASE i.Value WHEN d.Value THEN 0 ELSE 1 END = 1
END

Bây giờ, hãy điền vào TestTable với một số dữ liệu:

WHILE (SELECT COUNT(*) FROM TestTable) < 15
  INSERT INTO TestTable
  SELECT RAND() * 1000, RAND() * 1000, RAND() * 1000
;

Đây là nội dung của nó trước những thay đổi tiếp theo:

ID          Attr1       Attr2       Attr3
----------- ----------- ----------- -----------
1           820         338         831
2           795         881         453
3           228         430         719
4           36          236         105
5           246         115         649
6           488         657         438
7           990         360         15
8           668         978         724
9           872         385         562
10          460         396         462
11          62          599         630
12          145         815         439
13          595         7           54
14          587         85          655
15          80          606         407

Và bây giờ chúng ta hãy thực hiện một số sửa đổi đối với nội dung:

UPDATE TestTable SET Attr2 = 35 WHERE ID = 3;
UPDATE TestTable SET Attr3 = 0 WHERE ID BETWEEN 6 AND 10;
INSERT INTO TestTable VALUES (1, 1, 1);
DELETE FROM TestTable WHERE ID = 14;

Đây là những gì chúng tôi có trong TestTable sau đó:

ID          Attr1       Attr2       Attr3
----------- ----------- ----------- -----------
1           820         338         831
2           795         881         453
3           228         35          719
4           36          236         105
5           246         115         649
6           488         657         0
7           990         360         0
8           668         978         0
9           872         385         0
10          460         396         0
11          62          599         630
12          145         815         439
13          595         7           54
15          80          606         407
16          1           1           1

Và đây là những gì đã được ghi lại:

ID          TableID     AttrName   OldValue    NewValue    Timestamp
----------- ----------- ----------- ----------- ----------- -----------------------
1           3           Attr2       430         35          2011-08-22 20:12:19.217
2           10          Attr3       462         0           2011-08-22 20:12:19.227
3           9           Attr3       562         0           2011-08-22 20:12:19.227
4           8           Attr3       724         0           2011-08-22 20:12:19.227
5           7           Attr3       15          0           2011-08-22 20:12:19.227
6           6           Attr3       438         0           2011-08-22 20:12:19.227
7           16          Attr1       NULL        1           2011-08-22 20:12:19.227
8           16          Attr3       NULL        1           2011-08-22 20:12:19.227
9           16          Attr2       NULL        1           2011-08-22 20:12:19.227
10          14          Attr1       587         NULL        2011-08-22 20:12:19.230
11          14          Attr2       85          NULL        2011-08-22 20:12:19.230
12          14          Attr3       655         NULL        2011-08-22 20:12:19.230

Tất nhiên, thiết lập đã được đơn giản hóa phần nào. Đặc biệt, tất cả các cột của bảng chính sẽ được ghi là cùng một loại và do đó, không cần phải chuyển đổi dữ liệu sang một số loại chung để bao gồm nhiều loại dữ liệu khác nhau. Nhưng có lẽ đó chỉ là những gì bạn cần. Và nếu không, tôi tin rằng điều này có thể cung cấp một khởi đầu tốt để triển khai giải pháp cuối cùng.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Theo dõi bảng ghi mới trong cơ sở dữ liệu sql

  2. Có thể sử dụng SqlGeography với Linq to Sql không?

  3. Các thay đổi về cấp phép Common Sense cho SQL Server 2014 Standard Edition

  4. Nhận giá trị cột từ chuỗi tên cột sql

  5. LIÊN KẾT TẤT CẢ và KHÔNG VÀO cùng nhau