是否有任何方法可以在PostgreSQL中的单个查询中创建触发器和触发器函数

时间:2017-06-22 03:27:01

标签: sql postgresql plpgsql ddl database-trigger

我有PostgreSQL的问题。我想在单个查询中创建触发器和触发器函数,因此我可以更快地创建触发器。 这是我的触发功能:

    CREATE FUNCTION public.tda_a1()
      RETURNS trigger
      LANGUAGE 'plpgsql'
      COST 100.0
      VOLATILE NOT LEAKPROOF 
      COST 100.0
    AS $BODY$
    BEGIN
      DELETE FROM ref_dati2 where kd_propinsi = OLD.kd_propinsi;
      RETURN OLD;
    END;
    $BODY$;

这就是触发器:

    CREATE TRIGGER tda_a1
      BEFORE DELETE
      ON public.ref_propinsi
      FOR EACH ROW
      EXECUTE PROCEDURE public.tda_a1();

我尝试将这些加入单个查询但失败了。也许有人可以帮助我。

1 个答案:

答案 0 :(得分:1)

更新感到困惑:

  

我有192个触发器。我想在单个查询中执行它们,就像我在Oracle中所做的那样

以下是对被误解的原帖的回答。它解决了一次性包装创建多个触发器的性能。虽然OP可能意味着在触发器本身中定义PGSQL,而不是单独的触发函数。

制备

t=# create schema s1;
CREATE SCHEMA
t=# set search_path to s1;
SET
t=# create table t1 (i int);
CREATE TABLE
t=# \timing on
Timing is on.

DO语句运行:

t=# do
$$
begin
for i in 1..99 loop
execute format('create function %I() returns trigger as $f$begin return new;end;$f$ language plpgsql','f'||i);
execute format('create trigger %I before delete on t1 for each row execute procedure %I()','t'||i,'f'||i);
end loop;
end;
$$
;
DO
Time: 54.545 ms

时间:Time: 54.545 ms

现在使用相同的DO生成分隔语句的脚本:

t=# do
$$
begin
for i in 1..99 loop
raise info '%', format('create function %I() returns trigger as $f$begin return new;end;$f$ language plpgsql;','f'||i);
raise info '%', format('create trigger %I before delete on t1 for each row execute procedure %I();','t'||i,'f'||i);
end loop;
end;
$$
;

将其保存到文件中:

t=# \! vi s1
:%s/INFO:  //g
-- adding select clock_timestamp(); and begin; end; to avoid overhead on autocommit each statement
t=# \! wc -l s1
202 s1

202行。增加了198个陈述加4个。扫地运行:

t=# drop schema s1 cascade;
DROP SCHEMA
t=# create schema s1;
CREATE SCHEMA
t=# set search_path to s1;
SET
t=# create table t1 (i int);
CREATE TABLE
t=# \i s1
        clock_timestamp
-------------------------------
 2017-06-22 07:49:05.78448+00
(1 row)

Time: 0.202 ms
CREATE FUNCTION
Time: 1.407 ms
CREATE TRIGGER
....
....
CREATE TRIGGER
Time: 1.033 ms
        clock_timestamp
-------------------------------
 2017-06-22 07:49:05.823402+00
(1 row)

时差:

t=# select '2017-06-22 07:49:05.823402+00'::timestamptz - '2017-06-22 07:49:05.78448+00'::timestamptz;
    ?column?
-----------------
 00:00:00.038922
(1 row)

时间38.922 ms

我做了几次测试,动态执行有时更快,有时候没有。您可以实现的主要性能提升是在一个事务中运行多行脚本。但同样 - 我们在这里比较毫秒...

另外 - 也许你的意思是ELSE一个声明?如果是这样的话,请用原始帖子更新你在Oracle中如何做到的代码示例