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

问题描述 投票:1回答:2

我有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();

我试图将它们加入一个查询但失败了。也许有人可以帮助我。

sql postgresql plpgsql ddl database-trigger
2个回答
1
投票

谢谢你的所有答案,但最后我找到了答案,我刚从查询中删除了这个脚本。

  NOT LEAKPROOF 
  COST 100.0

这是pgadmin的默认设置,当我删除它时,我可以在单个查询中运行触发器,尽可能多地触发


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中完成它

© www.soinside.com 2019 - 2024. All rights reserved.