这个查询有什么问题。它在TRUNCATE上或附近给出了语法错误

时间:2016-05-03 09:43:07

标签: sql postgresql function plpgsql

我正在创建一个postgresSql函数来返回临时表中的所有行。我希望在我的函数启动时删除表中的所有行但是它在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;

1 个答案:

答案 0 :(得分:1)

你的功能有很多错误,很难知道从哪里开始。也不可能为您提供正确的解决方案,因为INSERT语句的列数多于VALUES子句。

一些基本要点:

  • 了解{{3}}。这应解决许多语法问题,例如SELECT之前的BEGIN语句。
  • 如果您的函数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;