我有几个数据库,供多个应用程序使用(其中一个是我们自己的数据库,其他一些我们无法控制其工作)。
Out软件必须知道上次更改数据库的时间。由于种种原因,我不愿赘述,因此我们决定为每个数据库创建一个新表,该表具有一个奇数字段:last_changed_on
,其值为GetDate()
。这样,我们自己的软件可以检查上次更改的时间,并将其检查到该数据库的存储日期,如果该日期比内存中的存储日期新,则可以执行该操作。
经过研究,我们认为与 Triggers 一起工作是可行的方法,但是从我在线上可以找到的触发器中,触发器会查看您为Updates设置的特定列。
我想知道的是,是否有一种方法可以自动执行该过程,或者只是在发生任何事情时触发触发器,只要明智地插入,更新,删除?
所以我正在寻找这样的东西:
CREATE TRIGGER LastModifiedTrigger
ON [dbo].[anytable]
AFTER INSERT, UPDATE, DELETE
AS
INSERT INTO dbo.LastModifiedTable (last_modified_on) VALUES (CURRENT_TIMESTAMP)
我知道上面的示例不是正确的触发器,对他们来说我还很陌生,所以我不确定该如何写。 可能有趣的是,我可以让自己的软件运行多个查询,从而自动为每个表和每个列创建查询,但是我宁愿避免这样做,因为长期跟踪所有这些触发器将是一件痛苦的事情。跑。 如果不必为每个单独的列名创建触发器,我希望每个数据库都尽可能少触发触发器。
编辑:澄清一下:我试图避免创建一个自动脚本,该脚本去扫描每个表,然后依次扫描每个表的每一列,以创建触发器来查看是否在那里进行了更改。目前,我最大的问题是在updates
上的触发行为,但我希望避免同时为insert
和delete
编辑2:为避免将来出现混乱,我正在寻找针对SQL Server(MS SQL / T SQL)和MySQL的此问题的解决方案
编辑3:事实证明,我非常错误地阅读了文档,并且(至少在MySql上)触发器在任何给定的更新列上均被激活,而无需定义特定的列。无论如何,我仍然想知道是否有一种方法可以使触发器少于数据库中每个表的触发器。 (即,对于任何类型的update()
为1,对于任何类型的insert()
为1,对于任何类型的delete()
为1
编辑4:忘记了覆盖1字段的参数会带来性能问题,我已经考虑了这一点,现在正在处理多行。我还通过我的软件代码为每个数据库创建了3个触发器(insert()
,update()
和delete()
),我真的希望可以避免这种情况,但是不能。
经过一堆互联网的探索之后,不断发现与我所寻找的结果相反的结果,以及一堆反复试验之后,我找到了解决方案。 首先,要使触发器不依赖于表(又称,每个表的触发器是不可能的,它不可能完成,这太糟糕了,保留它会很不错超出程序代码,但是我无能为力。
第二:关于不特定于列的更新的问题是一个错误,这是由于我搜索触发器不依赖于特定列的部分仅给了我一些特定的触发器的例子。 以下解决方案适用于MySql,我尚未在SQL Server上对其进行测试,但我希望它不会有太大区别。
CREATE TRIGGER [tablename]_last_modified_insert
AFTER INSERT/UPDATE/DELETE ON [db].[tablename]
FOR EACH ROW
BEGIN
INSERT INTO [db].last_modified(last_modified_on)
VALUES(current_timestamp())
END
关于动态创建这些触发器,下面显示了如何使其工作: 第一个查询:
SHOW TABLES
我运行上述查询以获取数据库中的所有表,排除我自己创建的last_modified
,并遍历所有表,为每个表创建3个触发器。
非常感谢Arvo和T2PS的答复,他们的意见为我指明了正确的方向并编写了解决方案,对此有所帮助。
答案 0 :(得分:0)
假设SQL Server触发器是按列的,则您略有偏离。 CREATE TRIGGER语法将触发器绑定到指定操作的命名表。将使用范围内的两个逻辑表(inserted
和deleted
来调用触发器,该逻辑表包含由导致触发器触发的操作修改的行;如果您想检查特定列的值或更改,则触发逻辑将需要针对那些逻辑表进行操作。
如果采用这种方法,则需要为希望以这种方式监视的每个表创建一个触发器;我们也有类似的需求(更细粒度地)跟踪更改,我们没有找到对应于架构/数据库中所有表的“伪表”。您还应该意识到,这样做会发挥锁定语义的作用,因为您将有多个表的触发器都针对同一行进行更新,这是单独操作的一部分-根据有效的并发模型,您可能会如果您希望多个DML查询针对您的数据库并发运行,则可以通过这样做来查看性能后果。
我建议改为检查上面Arvo的评论链接的适用性;查询系统视图更有可能避免在场景中使用触发器来避免争用(以及其他与性能相关的问题)。
答案 1 :(得分:0)
经过一堆互联网的探索之后,不断发现与我所寻找的结果相反的结果,以及一堆反复试验之后,我找到了解决方案。 首先,要使触发器不依赖于表(又称,每个表的触发器是不可能的,它不可能完成,这太糟糕了,保留它会很不错超出程序代码,但是我无能为力。
第二:关于不特定于列的更新的问题是一个错误,这是由于我搜索触发器不依赖于特定列的部分仅给了我一些特定的触发器的例子。 以下解决方案适用于MySQL,但我尚未在SQL Server上对其进行测试,但我希望它不会有太大区别。
CREATE TRIGGER [tablename]_last_modified_insert
AFTER INSERT/UPDATE/DELETE ON [db].[tablename]
FOR EACH ROW
BEGIN
INSERT INTO [db].last_modified(last_modified_on)
VALUES(current_timestamp())
END
关于动态创建这些触发器,下面显示了如何使其工作: 第一个查询:
SHOW TABLES
我运行上述查询以获取数据库中的所有表,排除我自己创建的last_modified
,并遍历所有表,为每个表创建3个触发器。
答案 2 :(得分:0)
也许您可以使用Audit for SQL Server:
CREATE SERVER AUDIT [ServerAuditName]
TO FILE
(
FILEPATH = N'C:\Program Files......'
)
ALTER SERVER AUDIT [ServerAuditName] WITH (STATE=ON)
GO
CREATE DATABASE AUDIT SPECIFICATION [mySpec]
FOR SERVER AUDIT [ServerAuditName]
ADD (INSERT, UPDATE, DELETE ON DATABASE::databasename BY [public])
WITH (STATE=ON)
GO
然后您可以查询更改:
SELECT *
FROM sys.fn_get_audit_file ('C:\Program Files......',default,default);
GO