我有一个有 120 列的表。我需要设置审计跟踪,如果发生更改,它将记录任何列。就像现在一样,我想我必须为每一列设置一个具有如下条件的触发器:
IF(NEW.columnName != OLD.columnName)
THEN //log the old value
这需要完成 120 次...虽然 20 年前我会接受这种方法,但今天我拒绝相信不可能自动执行这样一个简单的过程来自动查找已更改的列。
这是我到目前为止发现的:
- NEW 和 OLD 都不是表,它是一种语言构造,因此您不能执行“SELECT NOW.*”或类似的操作。
- 触发器中不允许使用动态 SQL(这可以解决问题)。
- 触发器中不允许使用动态 SQL 的过程(说真的,Oracle,无论如何,看起来您已经非常努力地禁用此功能)。
我想将 BEFORE 和 AFTER 触发器与临时表和变量结合使用,这可能会解决问题,但是仍然需要动态 SQL。我感觉我走进了死胡同。
有没有办法解决这个问题?
附带问题:这在 PostgreSQL 中可能吗?
UPDATE:我发现了两个潜在的解决方案,但对我来说它们都不够清晰:
- 使用 EVENTS 作为将触发器与动态 SQL 结合使用的解决方法解决方法 https://stackoverflow.com/questions/12575631/workaround-for-dynamic-statements-in-stored-procedures-called-from-triggers。我必须承认,我不太明白这一点,这是否意味着 EVENT 无论如何都会每秒触发?
-
本文 http://codewordhank.com/sql-server/dynamic-sql-and-a-trigger-gotcha/说只要与临时表一起使用,就可以在触发器内使用动态SQL。那还是用动态SQL,所以不太明白。
有趣的是,几年前我在实现基于动态触发器的审计日志时遇到了同样的问题。我提出的解决方案是简单地生成 SQL 触发器代码,然后可以(自动)应用该代码来替换旧的触发器定义。如果没记错的话,我创建了几个由 PHP 脚本处理的 SQL 模板,该脚本又根据“SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE ...”输出完整的触发器定义是的,触发器代码很大,但它有效!希望有一点帮助=)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)