postgresql - 构建例程以在 Postgres 中生成 CREATE TRIGGER 代码
问题描述
我还没有找到一种直接的方法来检索触发器定义代码。我的意思是触发器/绑定声明,而不是触发器函数。我想我会使用一些系统目录来构建一个脚本。以下不完整的版本会产生合理的输出:
CREATE OR REPLACE FUNCTION dba.ddl_get_build_trigger_code(trigger_id oid) -- I starting from having the OID.
RETURNS text
AS $BODY$
DECLARE
trigger_name_in text;
code text;
BEGIN
/*
What the original declaration looks like:
CREATE TRIGGER trigger_hsys_after_delete
AFTER DELETE
ON data.hsys
REFERENCING OLD TABLE AS deleted_rows
FOR EACH STATEMENT
EXECUTE PROCEDURE data.trigger_function_log_deletion_count();
*/
SELECT tgname FROM pg_trigger WHERE oid = trigger_id INTO trigger_name_in; -- information_schema tables don't use PG OIDs.
RETURN
'CREATE TRIGGER ' || trigger_name || chr(10) ||
chr(9) || action_timing || ' ' || event_manipulation || chr(10) ||
chr(9) || 'ON ' || event_object_schema || '.' || event_object_table ||
CASE WHEN action_reference_old_table IS NOT NULL THEN
chr(10) || chr(9) || 'REFERENCING OLD TABLE AS ' || action_reference_old_table || chr(10) END ||
-- CASE WHEN action_reference_new_table IS NOT NULL THEN
-- chr(10) || chr(9) || 'REFERENCING NEW TABLE AS ' || action_reference_new_table || chr(10) END ||
chr(9) || 'FOR EACH ' || action_orientation || chr(10) ||
chr(9) || action_statement || ';' as create_trigger_code
FROM information_schema.triggers
WHERE trigger_name = trigger_name_in;
END;
$BODY$
LANGUAGE plpgsql;
这是一个示例,与我的实际情况相匹配:
CREATE TRIGGER trigger_hsys_after_delete
AFTER DELETE
ON data.hsys
REFERENCING OLD TABLE AS deleted_rows
FOR EACH STATEMENT
EXECUTE PROCEDURE trigger_function_log_deletion_count();
其中还有几个属性information_schema.triggers
可能具有值,例如 action_reference_new_table。当我启用下面action_reference_new_table
的NULL
行时,脚本返回NULL
:
CASE WHEN action_reference_new_table IS NOT NULL THEN
chr(10) || chr(9) || 'REFERENCING NEW TABLE AS ' || action_reference_new_table || chr(10) END ||
我不明白为什么NULL
for 的值action_reference_new_table
会破坏我的连接代码并产生整个结果NULL
。
除了对这个特定问题的帮助之外,请随时指出我应该做些什么来编写更明智的 PL/PgSQL 代码。事实证明,我要掌握它比我想象的要难。
解决方案
只需使用
SELECT pg_get_triggerdef(oid)
FROM pg_trigger
WHERE tgname = trigger_name_in;
此外,在编写 SQL 代码时,切勿使用字符串连接。SQL注入的危险太大了。将format()
函数与%I
占位符一起使用。
推荐阅读
- c# - Visual Studio 2019 实体框架启用迁移错误
- windows - 来自网络 URL 的 DirectShow RenderFile 存在严重缺陷。如何避免?
- android - 我的应用程序发布前报告中的兼容性问题:android.os.strictmode.NonSdkApiUsedViolation
- python - 为什么这段代码变成了一个无限循环?
- python - 如何在 Tkinter 中重置下拉菜单的值和不显示图像?
- c# - 在网络浏览器中单击时出现奇怪的错误
- javascript - http 响应正文始终为空或未定义
- go - 如何将 wav 文件加载到 PCM 编码的字节数组中
- javascript - 每次浏览器通过开发刷新时,firebase 用户都会被注销
- asp.net - 如何在 Visual Studio 2019 中创建 ASP.NET 网站?