2016-05-03 16 views
0

我正在做一個postgresSql函數來返回臨時表中的所有行。我想在我的函數開始時從表中刪除所有行但它給我在TRUNCATE上或附近的語法錯誤。 這是我的查詢 -這個查詢有什麼問題。它給我在TRUNCATE上或附近的語法錯誤

CREATE OR REPLACE FUNCTION public.monthly_data_of_antenatal_care(hospitalId integer) 
    RETURNS SETOF antenatal_care_temp AS $$ 
    SELECT DISTINCT * FROM antenatal_care_temp group by hospital_id,antenatal_temp_id; 
BEGIN 
    TRUNCATE TABLE antenatal_care_temp RESTART IDENTITY; 
FOR 
    select hospital_id from mas_hospital where parent_institute_id = $1 or hospital_id = $1 
    LOOP 
     RETURN QUERY EXECUTE 
     'insert into table antenatal_care_temp(total,bpl,sc,st,below_19,jsy_reg,early_reg,high_risk_an,prophylaxis_i,prophylaxis_c1,prophylaxis_c2,treatment_i, 
treatment_c1,treatment_c2,an_checkups_1,an_checkups_2,an_checkups_3,an_checkups_4,an_checkups_5,tt_a_1,tt_i_1,tt_a_2,tt_i_2,data_type) values(
(select count(*) from ph_anc_survey where Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
(select count(*) from ph_anc_survey where bpl_status = 'Y' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
0,0, 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey where jsy_flag = 'Yes' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
0, 
(select count(*) from ph_anc_survey where complication != '' and Extract(month from reg_date) = Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
0,0,0 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
0, 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1), 
0, 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) = Extract(month from now()) and pas.hospital_id = $1) 
'current', 
$1 
); 

insert into table antenatal_care_temp(total,bpl,sc,st,below_19,jsy_reg,early_reg,high_risk_an,prophylaxis_i,prophylaxis_c1,prophylaxis_c2,treatment_i, 
treatment_c1,treatment_c2,an_checkups_1,an_checkups_2,an_checkups_3,an_checkups_4,an_checkups_5,tt_a_1,tt_i_1,tt_a_2,tt_i_2,data_type) values(
(select count(*) from ph_anc_survey where Extract(month from reg_date) between 4 and Extract(month from now()) and hospital_id = $1), 
(select count(*) from ph_anc_survey where bpl_status = 'Y' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
0,0, 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey where jsy_flag = 'Yes' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
0, 
(select count(*) from ph_anc_survey where complication != '' and Extract(month from reg_date) between 4 and Extract(month from now()) and Extract(year from reg_date) = Extract(year from now()) and hospital_id = $1), 
0,0,0 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
0, 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1), 
0, 
(select count(*) from ph_anc_survey pas join ph_anc_followup paf on pas.anc_reg_id = paf.anc_reg_id where paf.age < 19 and Extract(year from paf.followup_date) = Extract(year from now()) and Extract(month from paf.followup_date) between 4 and Extract(month from now()) and pas.hospital_id = $1) 
'cumulative', 
$1 
)'; 
    END LOOP; 
END 
$$ LANGUAGE sql; 
+0

我想TRUNCATE後無表的關鍵字應該解決這個問題? –

+2

'語言SQL'不支持'execute'(或'begin ... end')您需要'language plpgsql'。在第一個'begin'之前,你也不能有'select'。選擇還需要一個目標來存儲數據的存儲位置。我也不認爲你可以用一個'execute'運行兩條語句。這兩個'inserts'都沒有'returns'子句,所以它們不會返回任何數據。 –

+1

整個函數看起來過於複雜,並且在循環中執行插入操作會降低性能。爲什麼不直接使用'insert ... select'?也許如果你向我們解釋了你真正**的問題,我們可以提出一個更好的解決方案。 –

回答

1

有如此多的問題與您的函數,這是很難知道從哪裏開始。也不可能給你一個正確的解決方案,因爲你的INSERT陳述比VALUES子句有更多的列。

一些基本要點:

  • 瞭解PL/pgSQL。這應該解決許多語法問題,例如BEGIN之前的SELECT聲明。
  • 如果您的功能RETURNS SETOF something您不需要先填充臨時表。最好你應該RETURN SETOF something,當要返回的數據是(可能)非常大時使用臨時表,但是你會指定RETURNS void(或可能是臨時表名)。但是,如果您完全擺脫臨時表,則應指定RETURNS TABLE (f1 int, f2 int, ...)
  • 在函數體中,儘可能多地從循環中計算出來。
  • 請勿創建大量的INSERT聲明,您自己不再瞭解以及哪個聲明會損害您的性能(在INSERT聲明中,您使用相同的子查詢產生14次數的聲明!)。將其分解成可管理的塊。

你應該產生看起來有點像這樣的功能:

CREATE OR REPLACE FUNCTION public.monthly_data_of_antenatal_care(hospitalId integer) 
    RETURNS TABLE (total int, bpl int, sc int, st int, below_19 int, ....) AS $$ 
DECLARE 
    hid  integer; 
    this_month timestamp; 
    cnt  integer; 
    fup  integer; 
BEGIN 
    this_month = date_trunc('month', now()); -- Outside of the loop 
    FOR hid IN 
     SELECT hospital_id FROM mas_hospital 
     WHERE parent_institute_id = $1 OR hospital_id = $1 
    LOOP 
     SELECT count(*) INTO cnt 
     FROM ph_anc_survey 
     WHERE date_trunc('month', reg_date) = this_month AND hospital_id = hid; 

     SELECT count(*) INTO fup 
     FROM ph_anc_survey pas JOIN ph_anc_followup paf USING (anc_reg_id) 
     WHERE paf.age < 19 AND date_trunc('month', paf.followup_date) = this_month 
      AND pas.hospital_id = hid; 
     -- More statements like above 

     RETURN NEXT VALUES (cnt, fup, 0, ...); -- Must match structure of RETURNS TABLE 
    END LOOP; 
    RETURN; 
END; 
$$ LANGUAGE plpgsql; 
相關問題