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

what is wrong in this query. It is giving me syntax error on or near TRUNCATE

我正在制作一个 postgresSql 函数来 return 来自临时 table 的所有行。我想在我的函数开始时删除 table 中的所有行但是它在 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 =  or hospital_id = 
   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 = ),
(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 = ),
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 = ),
(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 = ),
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 = ),
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 = ),
(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 = ),
(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 = ),
(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 = ),
(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 = ),
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 = ),
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 = )
'current',

);

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 = ),
(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 = ),
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 = ),
(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 = ),
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 = ),
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 = ),
(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 = ),
(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 = ),
(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 = ),
(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 = ),
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 = ),
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 = )
'cumulative',

)';
   END LOOP;
END
$$  LANGUAGE sql;

你的函数有太多错误以至于很难知道从哪里开始。也不可能给你一个正确的解决方案,因为你的 INSERT 语句比 VALUES 子句有更多的列。

一些基本点:

  • 学习PL/pgSQL。这应该可以解决许多语法问题,例如 BEGIN.
  • 之前的 SELECT 语句
  • 如果您的函数 RETURNS SETOF something 您不需要先填充临时 table。最好你应该RETURN SETOF something,当要返回的数据(可能)非常大时使用临时table,但是你会指定RETURNS void(或者可能是临时table姓名)。但是,如果你完全摆脱临时 table 你应该指定 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 =  OR hospital_id = 
    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;