Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带参数的Postgresql触发器函数_Sql_Postgresql_Triggers - Fatal编程技术网

带参数的Postgresql触发器函数

带参数的Postgresql触发器函数,sql,postgresql,triggers,Sql,Postgresql,Triggers,我想在postgresql中名为的表上创建一个触发器,以更新另一个名为student的表中的值 我试着用下面的方法来做。但是我得到一个错误,在“OLD”附近有语法错误。我不明白这有什么问题。这是我的代码: CREATE OR REPLACE FUNCTION upd8_cred_func (id1 VARCHAR, gr1 VARCHAR,id2 VARCHAR, gr2 VARCHAR) RETURNS void AS $$ BEGIN IF (id1=i

我想在postgresql中名为的表上创建一个触发器,以更新另一个名为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);

您不需要将新的和旧的as参数传递给触发器函数。它们在那里自动可用:

:

触发器函数必须声明为不带参数且返回类型触发器的函数。(触发器函数通过特殊传递的TriggerData结构接收其输入,而不是以普通函数参数的形式。)

关于传递到触发器过程的记录,请参阅:

当调用PL/pgSQL函数作为触发器时,会在顶级块中自动创建几个特殊变量。它们是:[…]新的,[…]旧的[…]

正如下面的注释所指出的那样,您仍然可以向触发器函数传递和使用参数。您将函数声明为不带参数,但在定义触发器时(通过
创建触发器
),可以添加一些参数

它们将作为
TG_NARG
(此类参数的数量)和
TG_ARGV[]
(文本值数组)用于触发器。

触发器函数可以有参数,但不能像普通函数一样传递这些参数(例如函数定义中的参数)。你可以得到同样的结果。。。在python中,您可以访问旧数据和新数据,如上面所述。例如,我可以在python中使用TD['new']['column_name']来引用column_name的新数据。您还可以访问特殊变量TD['args']。因此,如果您愿意:

create function te() returns trigger language plpython2u as $function$
    plpy.log("argument passed 1:%s 2:%s" %(TD['args'][0], TD['args'][1], ))
$function$

create constraint trigger ta after update of ttable
for each for execute procedure te('myarg1','myarg2');
当然,这些参数是静态的,但是,当从多个触发器声明调用公共触发器函数时,它们很有用。我非常确定,其他存储过程语言也可以使用相同的变量。(很抱歉,如果代码不能一字不差地工作,但是,我确实练习过这种技术,因此我知道您可以传递参数!)。

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

CREATE TABLE my_table ( ID SERIAL PRIMARY KEY ); -- onelined for compactness

CREATE OR REPLACE FUNCTION raise_a_notice() RETURNS TRIGGER AS
$$
DECLARE
    arg TEXT;
BEGIN
    FOREACH arg IN ARRAY TG_ARGV LOOP
        RAISE NOTICE 'Why would you pass in ''%''?',arg;
    END LOOP;
    RETURN NEW; -- in plpgsql you must return OLD, NEW, or another record of table's type
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER no_inserts_without_notices BEFORE INSERT ON my_table
FOR EACH ROW EXECUTE PROCEDURE raise_a_notice('spoiled fish','stunned parrots');

INSERT INTO my_table DEFAULT VALUES;

-- the above kicks out the following:
--
-- NOTICE:  Why would you pass in 'spoiled fish'?
-- NOTICE:  Why would you pass in 'stunned parrots'?
--

还有一些其他的好处,比如在中讨论的
TG\u NARGS
(了解在没有循环的情况下得到了多少arg)。这里还有关于如何获取触发表名称的信息,以防一个触发函数跨越多个表时有大部分但不完全共享的逻辑。

对于plpgsql触发函数不能接受参数而言,这个答案(也可以说是规范)是错误的。它们必须简单地定义为“不带参数”。传递给触发器函数的参数可以使用
TG_ARGV
数组(其索引从0开始)进行访问。这是在文档中指定的。我已经发布了一个答案,其中包含本机
plpgsql
脚本语言的演示,如果您想看一下的话。谢谢您的编辑。由于错误信息得到纠正,否决票被取消。C: