2017-05-30 24 views
0

我試圖做一個觸發器,對錶中的更新做出響應(約會),然後調用過程(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

回答

0

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一樣多。這是你原來的基於觸發器的邏輯所做的。

相關問題