带参数的PostgreSQL触发器函数

ghg1uchk  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(4)|浏览(219)

我想在postgresql中的一个名为takes的表上创建一个触发器,以更新另一个名为student的表中的值。我试图用下面的方法来做这件事。但是我得到一个错误,在“OLD”附近有语法错误。我不明白这有什么问题。这是我的代码:

  1. CREATE OR REPLACE FUNCTION upd8_cred_func
  2. (id1 VARCHAR, gr1 VARCHAR,id2 VARCHAR, gr2 VARCHAR)
  3. RETURNS void AS $$
  4. BEGIN
  5. IF (id1=id2 and gr1 is null and gr2 is not null) THEN
  6. update student set tot_cred = tot_cred + 6 where id = id1;
  7. END IF;
  8. RETURN;
  9. END;
  10. $$ LANGUAGE plpgsql;
  11. CREATE TRIGGER upd8_cred AFTER UPDATE ON takes
  12. FOR EACH ROW EXECUTE PROCEDURE
  13. upd8_cred_func(OLD.id, OLD.grade, NEW.id, NEW.grade);

字符串

3xiyfsfu

3xiyfsfu1#

你不需要将NEW和OLD作为参数传递给trigger函数。它们在那里 * 自动 * 可用:
http://www.postgresql.org/docs/9.1/interactive/trigger-definition.html
trigger函数必须声明为不带参数并返回类型trigger的函数。(trigger函数通过特殊传递的TriggerData结构接收其输入,而不是以普通函数参数的形式。)
关于传递给触发器过程的记录,请参见http://www.postgresql.org/docs/9.1/interactive/plpgsql-trigger.html
当一个PL/pgSQL函数作为触发器被调用时,在顶层块中会自动创建几个特殊的变量。它们是:[...] NEW,[...] OLD [...]
正如SeldomNeedy在下面的注解中指出的那样,你仍然可以向触发器函数传递和使用参数。你 * 声明 * 函数不带参数,但是当 * 定义 * 触发器(通过CREATE TRIGGER)时,你可以添加一些参数。
它们将作为TG_NARG(此类参数的数量)和TG_ARGV[]text 值的数组)可用于触发器。

eagi6jfj

eagi6jfj2#

正如Greg所述,触发器函数可以接受参数,但函数本身不能有声明的参数。下面是plpgsql中的一个简单示例:

  1. CREATE TABLE my_table ( ID SERIAL PRIMARY KEY ); -- onelined for compactness
  2. CREATE OR REPLACE FUNCTION raise_a_notice() RETURNS TRIGGER AS
  3. $$
  4. DECLARE
  5. arg TEXT;
  6. BEGIN
  7. FOREACH arg IN ARRAY TG_ARGV LOOP
  8. RAISE NOTICE 'Why would you pass in ''%''?',arg;
  9. END LOOP;
  10. RETURN NEW; -- in plpgsql you must return OLD, NEW, or another record of table's type
  11. END;
  12. $$ LANGUAGE plpgsql;
  13. CREATE TRIGGER no_inserts_without_notices BEFORE INSERT ON my_table
  14. FOR EACH ROW EXECUTE PROCEDURE raise_a_notice('spoiled fish','stunned parrots');
  15. INSERT INTO my_table DEFAULT VALUES;
  16. -- the above kicks out the following:
  17. --
  18. -- NOTICE: Why would you pass in 'spoiled fish'?
  19. -- NOTICE: Why would you pass in 'stunned parrots'?
  20. --

字符串
the docs中还讨论了一些其他的好东西,比如TG_NARGS(不用循环就能知道你得到了多少个参数)。还有关于如何获取触发表的名称的信息,以防你有一个跨越多个表的查询函数的大部分但不完全共享的逻辑。

展开查看全部
rdlzhqv9

rdlzhqv93#

trigger函数可以有参数,但是不能像普通函数那样传递这些参数(例如,函数定义中的参数)。你可以得到相同的结果......在python中,你可以像上面的答案描述的那样访问OLD和NEW数据。例如,我可以在python中使用TD 'new']'column_name']来引用column_name的新数据。您还可以访问特殊变量TD 'args']。因此,如果您愿意:

  1. create function te() returns trigger language plpython2u as $function$
  2. plpy.log("argument passed 1:%s 2:%s" %(TD['args'][0], TD['args'][1], ))
  3. $function$
  4. create constraint trigger ta after update of ttable
  5. for each for execute procedure te('myarg1','myarg2');

字符串
当然,这些参数是静态的,但是,当从多个触发器声明中调用公共触发器函数时,它们很有用。我很确定相同的变量可用于其他存储过程语言。(如果代码不能逐字工作,请原谅,但是,我确实练习了这种技术,所以我知道你可以传递参数!)。

zwghvu4y

zwghvu4y4#

trigger function不能有如下所示的参数(声明的参数):

  1. CREATE FUNCTION my_func(num INTEGER) RETURNS trigger
  2. AS $$ -- Here
  3. BEGIN
  4. END;
  5. $$ LANGUAGE plpgsql;

字符串
否则会出现以下错误:
错误:触发器函数不能有声明的参数
而且,事件触发器函数不能有如下所示的参数(声明的参数):

  1. CREATE FUNCTION my_func(num INTEGER)
  2. RETURNS event_trigger -- Here
  3. LANGUAGE plpgsql
  4. AS $$
  5. BEGIN
  6. END;
  7. $$;


否则会出现以下错误:
错误:事件触发器函数不能有声明的参数
我尝试了触发器和事件触发器函数,并制作了如下所示的备忘录:

  • 触发器和事件触发器的功能:
  • 必须没有参数,否则有错误。
  • 必须分别用触发器和事件触发器调用,否则会出错。
  • 不能用LANGUAGE SQL创建,否则会出现错误。
  • 必须在RETURNS <type>子句中分别具有triggerevent_trigger,以分别与trigger和event_trigger一起使用,否则会出现错误。
  • 触发器和事件触发器程序不存在。
展开查看全部

相关问题