如何从函数传递参数到创建TRIGGER?

问题描述:

我试图做一个触发器,对表中的更新做出响应(约会),然后调用过程(proc1())。该过程需要获取参数,以便在不同的表上插入一个基于这些参数的新行(medical_folder)。过程不能有参数,但有点搜索后,我发现,你可以使用的方法类似下面有点强迫,虽然自己的方式:如何从函数传递参数到创建TRIGGER?

Passing arguments to a trigger function

通过以上为我基地我做了如下UDF:

CREATE OR REPLACE FUNCTION AppointmentUpdate(docAMKA bigint, patAMKA bigint, dateNtime timestamp, conclusion varchar(500),cure2 varchar(500), drug_id integer) 
RETURNS void AS $$ 
DECLARE 
    patAMKAv2 text; 
    drug_idv3 text; 
BEGIN 
    patAMKAv2 := cast(AppointmentUpdate.patAMKA as text); 
    drug_idv3 := cast(AppointmentUpdate.drug_id as text); 
    DROP TRIGGER IF EXISTS tr1 on appointments; 
    CREATE TRIGGER tr1 BEFORE UPDATE ON appointments 
    EXECUTE PROCEDURE proc1(patAMKAv2,cure2,drug_idv3); 
    UPDATE appointments 
    SET diagnosis = conclusion 
    WHERE patientamka = patAMKA 
     AND doctoramka = docAMKA 
     AND t = dateNtime; 
END; 
$$ LANGUAGE plpgsql; 

我的步骤如下:

CREATE OR REPLACE FUNCTION proc1() 
RETURNS trigger AS $$ 
declare 
    newid integer; 
BEGIN 
    newid =((select max(medical_folder.id) from medical_folder)+1); 
    INSERT INTO medical_folder AS Medf(id,patient,cure,drug_id) 
    VALUES(newid,cast(TG_ARGV[0] as bigint),TG_ARGV[1],cast(TG_ARGV[2] as integer)); 
RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

如果我运行它是我在PROC得到一个错误1()这里cast(TG_ARGV[0] as bigint)并且它似乎在UDF中而不是发送参数的值它自己发送参数(例如,我这样做而不是EXECUTE PROCEDURE proc1(patAMKAv2,cure2,drug_idv3);)。有没有什么办法可以强制它取得值?我现在可以在不使用TRIGGER的情况下轻松完成这些工作,并且只需制作一个UDF即可完成所有工作,但不幸的是,我必须使用TRIGGER来完成这项工作。

P.S.2:我尝试使用function_name.variable_name,而不是仅仅VAR_NAME使用$ 1,$ 2,$ 3,...,$ N也试过。

+0

我希望你不是试图使用'select max(medical_folder.id)+ 1'这个破坏的反模式来生成唯一的ID - 为此使用一个序列。在多个事务插入到该表中的情况下,使用'max()'不起作用。 –

+0

不要担心,这不是要发布任何类型的产品或任何东西。如有必要,这可以进一步解决。至于现在我的问题是让这个过程按照我所需要的参数进行。这更多(实际上更多)是一个不成熟的项目。感谢您指出,无论如何表示赞赏。 – Sokratis

CREATE TRIGGER docs

参数
执行触发时将被提供给该功能的参数的可选逗号分隔的列表。参数是文字串常量。 简单的名字和数字常数也可以写在这里,但它们都会被转换为字符串。

http://rextester.com/OCA59277

您可能能够达到你所用,虽然动态SQL(see EXECUTE)尝试。但我相信你会让事情变得复杂。你想要做的只是获取参与UPDATE声明的行或ID。 PostgreSQL的DML语句(INSERT,UPDATE & DELETE)有一个RETURNING子句。另外,您可以在writeable CTEs的单个语句中实际编写更多的DML(子)语句。像这样的东西应该足够了:

WITH upd AS (
    UPDATE appointments 
    SET  diagnosis = conclusion 
    WHERE  patientamka = patAMKA 
    AND  doctoramka = docAMKA 
    AND  t   = dateNtime 
    RETURNING * 
) 
INSERT INTO medical_folder(patient, cure, drug_id) 
SELECT patAMKAv2, cure2, drug_idv3 
FROM upd; 

:在写这个,我意识到,你实际上不使用的任何字段从UPDATE,但使用FROM upd将确保尽可能多的行会被插入到medical_folderappointments一样多。这是你原来的基于触发器的逻辑所做的。