【发布时间】:2015-10-16 15:50:23
【问题描述】:
我想验证向某些表添加触发器的数据库迁移的正确性。我正在使用sqitch,所以我想找到一种方法来使用 SQL 查询来检查它。我相信使用 postgres 系统表应该是可能的,但我目前找不到这样做的方法。
【问题讨论】:
标签: sql database postgresql triggers
我想验证向某些表添加触发器的数据库迁移的正确性。我正在使用sqitch,所以我想找到一种方法来使用 SQL 查询来检查它。我相信使用 postgres 系统表应该是可能的,但我目前找不到这样做的方法。
【问题讨论】:
标签: sql database postgresql triggers
使用目录pg_trigger。
简单查找表books:
select tgname
from pg_trigger
where not tgisinternal
and tgrelid = 'books'::regclass;
tgname
---------------
books_trigger
(1 row)
使用pg_proc获取触发函数的来源:
select tgname, proname, prosrc
from pg_trigger
join pg_proc p on p.oid = tgfoid
where not tgisinternal
and tgrelid = 'books'::regclass;
tgname | proname | prosrc
---------------+---------------+------------------------------------------------
books_trigger | books_trigger | +
| | begin +
| | if tg_op = 'UPDATE' then +
| | if new.listorder > old.listorder then +
| | update books +
| | set listorder = listorder- 1 +
| | where listorder <= new.listorder +
| | and listorder > old.listorder +
| | and id <> new.id; +
| | else +
| | update books +
| | set listorder = listorder+ 1 +
| | where listorder >= new.listorder +
| | and listorder < old.listorder +
| | and id <> new.id; +
| | end if; +
| | else +
| | update books +
| | set listorder = listorder+ 1 +
| | where listorder >= new.listorder +
| | and id <> new.id; +
| | end if; +
| | return new; +
| | end
(1 row)
pg_get_triggerdef()函数使用示例:
select pg_get_triggerdef(t.oid) as "trigger declaration"
from pg_trigger t
where not tgisinternal
and tgrelid = 'books'::regclass;
trigger declaration
--------------------------------------------------------------------------------------------------------------
CREATE TRIGGER books_trigger BEFORE INSERT OR UPDATE ON books FOR EACH ROW EXECUTE PROCEDURE books_trigger()
(1 row)
在 Sqitch verify 脚本中,您可以使用匿名代码块,例如:
do $$
begin
perform tgname
from pg_trigger
where not tgisinternal
and tgrelid = 'books'::regclass;
if not found then
raise exception 'trigger not found';
end if;
end $$;
【讨论】:
tgnames 看起来像这样 RI_ConstraintTrigger_c_195564,而不是 1 个。我使用的是 postgresql 9.4。
not tgisinternal 跳过它们,就像在编辑后的答案中一样。
deploy 脚本,该脚本将创建添加新触发器。然后它运行verify 脚本来检查触发器是否被正确添加。如果验证脚本运行时没有任何错误,即使deploy 因某种原因失败,它也会假设一切正常。如果verify 脚本会抛出一些错误,sqitch 就会知道某些事情失败了,所以它会运行revert 脚本。
verify 脚本中使用DO 命令和ASSERT 或RAISE。查看更新的答案。
按触发器名称检查,您可以这样做:
select trigger_name from information_schema.triggers
WHERE trigger_name = 'your_trigger_name'
也可以选择其他信息。
select event_object_schema as table_schema,
event_object_table as table_name,
trigger_schema,
trigger_name,
string_agg(event_manipulation, ',') as event,
action_timing as activation,
action_condition as condition,
action_statement as definition
from information_schema.triggers
group by 1,2,3,4,6,7,8
order by table_schema,
table_name;
栏目详情
如果您不想选择event_manipulation,可以删除查询中的group by。
【讨论】: