我想“创建或替换”postgres表的触发器。但是,没有这样的sql表达式。
我看到我可以先做“DROP TRIGGER IF EXISTS”(http://www.postgresql.org/docs/9.5/static/sql-droptrigger.html)。
我的问题是:
请注意,oracle(https://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm)中有“创建或替换触发器”。然后,
答案 0 :(得分:45)
无法创建或替换触发器,但可以这样做
DROP TRIGGER IF EXISTS yourtrigger_name on "yourschemaname"."yourtablename";
答案 1 :(得分:16)
Postres有事务DDL,所以BEGIN > DROP > CREATE > COMMIT is the equivalent of
创建或替换`
https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis是关于postgre的事务性DDL与其他系统(如oracle)比较的一个很好的写法
关于触发器的当前postgres计划功能(https://wiki.postgresql.org/wiki/Todo#Triggers)不包括添加REPLACE
语法
答案 2 :(得分:5)
您应该使用两个语句:一个用于放置触发器,另一个用于创建触发器。
示例:
DROP TRIGGER IF EXISTS my_trigger
ON my_schema.my_table;
CREATE TRIGGER my_trigger
BEFORE INSERT OR UPDATE
ON my_schema.my_table
FOR EACH ROW EXECUTE PROCEDURE my_schema.my_function();
答案 3 :(得分:3)
您可以在SQL中将CREATE OR REPLACE FUNCTION trigger_function
与以下脚本结合使用:
DO $$
BEGIN
IF NOT EXISTS(SELECT *
FROM information_schema.triggers
WHERE event_object_table = 'table_name'
AND trigger_name = 'trigger_name'
)
THEN
CREATE TRIGGER trigger_name AFTER INSERT ON table_name FOR EACH ROW EXECUTE PROCEDURE trigger_function();
END IF;
END;
$$
答案 4 :(得分:1)
您可以使用以下代码。
DO $$ BEGIN
CREATE (trigger, type , ...);
EXCEPTION
WHEN others THEN null;
END $$;
样本:
DO $$ BEGIN
CREATE TRIGGER trigger_workIDExist
BEFORE INSERT OR UPDATE ON "GalleryModel"
FOR EACH ROW EXECUTE PROCEDURE check_workIDExist();
EXCEPTION
WHEN others THEN null;
END $$;
答案 5 :(得分:0)
这是一个 Python 脚本,它从 postgresql 转储文件中提取所有触发器以进行重建。我使用了许多与 QGIS 配合得很好的堆叠视图;这对维护依赖视图有很大帮助。
基于 Ali Bagheri 的精彩回答。
import pathlib
import re
import sys
re_pat_str = r'^\s*CREATE TRIGGER.*?;\s*$'
sql_wrapper_str = """
DO $$ BEGIN
{trigger_str}
EXCEPTION WHEN others THEN null;
END $$;
"""
if __name__ == "__main__":
sql_file = pathlib.Path(sys.argv[1])
with sql_file.open("r", encoding="utf8") as f:
sql_str = f.read()
re_pat = re.compile(re_pat_str, re.MULTILINE | re.DOTALL)
parts = []
for i, m in enumerate(re_pat.finditer(sql_str)):
parts.append(sql_wrapper_str.format(trigger_str=m[0].strip()))
new_sql_str = "\n".join(parts)
new_sql_file = sql_file.parent / f'{sql_file.stem}.trigger{sql_file.suffix}'
with new_sql_file.open("w", encoding="utf8") as f:
f.write(new_sql_str)