将任何事务存储在日志 table SQL 服务器中
Store any transaction in log table SQL Server
我的 SQL 服务器数据库中有很多 table。当发生任何动作时,例如 Insert
、Update
、Delete
,我想将数据存储在 Log
table 中,如下所示:
Product
table:
| ID | Name | Other |
| --- | ------- | --- |
| 1 | Book | ... |
| 2 | Bicycle | ... |
如果发生任何插入、更新或删除,我想要这样的东西:
Log
table:
| ID | RowId | TableName | Action |
| --- | ------- | ---------- | ------ |
| 1 | 1 | Product | Insert |
| 2 | 2 | Product | Insert |
| 3 | 15 | Category | Update |
| 4 | 60 | Customer | Insert |
我正在使用 Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) 具有高级服务的快捷版 - 我可能无法使用某些功能(参考文档)。
对于单个 table,trigger 是个好主意,而且效果很好,但是所有 table 呢?如示例所示,Category
和 Customer
table 是我数据库中的其他 table。
如果你的问题是触发器的数量,你应该创建;然后创建一个作业以在创建新 table 时创建触发器。下面的代码使用特定的命名公式检查没有那种触发器的 tables。在我的示例中 tablename 加上 '_dml_audit'。无论如何你都可以改变它。
Set NOCOUNT ON
select Concat (QUOTENAME(sch.name) , '.' , QUOTENAME(tbl.name)) TableNames
into #Tables
From sys.tables tbl
INNER JOIN sys.schemas sch on sch.schema_id = tbl.schema_id
LEFT JOIN sys.triggers trg on tbl.object_id = trg.parent_id and trg.name like tbl.name + '_dml_audit'
Where trg.object_id is null
GO
exec sp_MSforeachtable 'IF ''?'' IN (Select TableNames FROM #Tables) Begin PRINT ''?'' END'
Drop Table #Tables
对于不支持#table的旧版本,使用这个:
Create Table TempTable (TableNames sysname)
GO
Insert TempTable
SELECT Concat ('[', sch.name , '].[' , tbl.name, ']') TableNames
From sys.tables tbl
INNER JOIN sys.schemas sch on sch.schema_id = tbl.schema_id
LEFT JOIN sys.triggers trg on tbl.object_id = trg.parent_id and trg.name like tbl.name + '_dml_audit'
Where trg.object_id is null
GO
exec sp_MSforeachtable 'IF ''?'' IN (Select TableNames FROM TempTable) Begin PRINT ''?'' END'
GO
Drop Table TempTable
用 PRINT 语句替换触发器定义并为其定义作业。
我的 SQL 服务器数据库中有很多 table。当发生任何动作时,例如 Insert
、Update
、Delete
,我想将数据存储在 Log
table 中,如下所示:
Product
table:
| ID | Name | Other |
| --- | ------- | --- |
| 1 | Book | ... |
| 2 | Bicycle | ... |
如果发生任何插入、更新或删除,我想要这样的东西:
Log
table:
| ID | RowId | TableName | Action |
| --- | ------- | ---------- | ------ |
| 1 | 1 | Product | Insert |
| 2 | 2 | Product | Insert |
| 3 | 15 | Category | Update |
| 4 | 60 | Customer | Insert |
我正在使用 Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) 具有高级服务的快捷版 - 我可能无法使用某些功能(参考文档)。
对于单个 table,trigger 是个好主意,而且效果很好,但是所有 table 呢?如示例所示,Category
和 Customer
table 是我数据库中的其他 table。
如果你的问题是触发器的数量,你应该创建;然后创建一个作业以在创建新 table 时创建触发器。下面的代码使用特定的命名公式检查没有那种触发器的 tables。在我的示例中 tablename 加上 '_dml_audit'。无论如何你都可以改变它。
Set NOCOUNT ON
select Concat (QUOTENAME(sch.name) , '.' , QUOTENAME(tbl.name)) TableNames
into #Tables
From sys.tables tbl
INNER JOIN sys.schemas sch on sch.schema_id = tbl.schema_id
LEFT JOIN sys.triggers trg on tbl.object_id = trg.parent_id and trg.name like tbl.name + '_dml_audit'
Where trg.object_id is null
GO
exec sp_MSforeachtable 'IF ''?'' IN (Select TableNames FROM #Tables) Begin PRINT ''?'' END'
Drop Table #Tables
对于不支持#table的旧版本,使用这个:
Create Table TempTable (TableNames sysname)
GO
Insert TempTable
SELECT Concat ('[', sch.name , '].[' , tbl.name, ']') TableNames
From sys.tables tbl
INNER JOIN sys.schemas sch on sch.schema_id = tbl.schema_id
LEFT JOIN sys.triggers trg on tbl.object_id = trg.parent_id and trg.name like tbl.name + '_dml_audit'
Where trg.object_id is null
GO
exec sp_MSforeachtable 'IF ''?'' IN (Select TableNames FROM TempTable) Begin PRINT ''?'' END'
GO
Drop Table TempTable
用 PRINT 语句替换触发器定义并为其定义作业。