我想在postgresql中的一个名为takes的表上创建一个触发器,以更新另一个名为student的表中的值。我试图用下面的方法来做这件事。但是我得到一个错误,在“OLD”附近有语法错误。我不明白这有什么问题。这是我的代码:
CREATE OR REPLACE FUNCTION upd8_cred_func
(id1 VARCHAR, gr1 VARCHAR,id2 VARCHAR, gr2 VARCHAR)
RETURNS void AS $$
BEGIN
IF (id1=id2 and gr1 is null and gr2 is not null) THEN
update student set tot_cred = tot_cred + 6 where id = id1;
END IF;
RETURN;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER upd8_cred AFTER UPDATE ON takes
FOR EACH ROW EXECUTE PROCEDURE
upd8_cred_func(OLD.id, OLD.grade, NEW.id, NEW.grade);
字符串
4条答案
按热度按时间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 值的数组)可用于触发器。eagi6jfj2#
正如Greg所述,触发器函数可以接受参数,但函数本身不能有声明的参数。下面是plpgsql中的一个简单示例:
字符串
在the docs中还讨论了一些其他的好东西,比如
TG_NARGS
(不用循环就能知道你得到了多少个参数)。还有关于如何获取触发表的名称的信息,以防你有一个跨越多个表的查询函数的大部分但不完全共享的逻辑。rdlzhqv93#
trigger函数可以有参数,但是不能像普通函数那样传递这些参数(例如,函数定义中的参数)。你可以得到相同的结果......在python中,你可以像上面的答案描述的那样访问OLD和NEW数据。例如,我可以在python中使用TD 'new']'column_name']来引用column_name的新数据。您还可以访问特殊变量TD 'args']。因此,如果您愿意:
字符串
当然,这些参数是静态的,但是,当从多个触发器声明中调用公共触发器函数时,它们很有用。我很确定相同的变量可用于其他存储过程语言。(如果代码不能逐字工作,请原谅,但是,我确实练习了这种技术,所以我知道你可以传递参数!)。
zwghvu4y4#
trigger function不能有如下所示的参数(声明的参数):
字符串
否则会出现以下错误:
错误:触发器函数不能有声明的参数
而且,事件触发器函数不能有如下所示的参数(声明的参数):
型
否则会出现以下错误:
错误:事件触发器函数不能有声明的参数
我尝试了触发器和事件触发器函数,并制作了如下所示的备忘录:
LANGUAGE SQL
创建,否则会出现错误。RETURNS <type>
子句中分别具有trigger
和event_trigger
,以分别与trigger和event_trigger一起使用,否则会出现错误。