否则错误出现在 postgressql 的函数中

Else error appears in function in postgressql

提问人:Samuele 提问时间:11/13/2023 更新时间:11/13/2023 访问量:20

问:

我在postgressql中有这个函数,p_flg_init设置if分支:

CREATE OR REPLACE FUNCTION dwh.f_dwh_post_dm_updt_vend_cust_serv(p_flg_init varchar DEFAULT 'N')
 RETURNS text
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$
DECLARE

   proc_step       varchar := NULL; 
   nTemId     numeric := NULL;
   qta_nobilia numeric := NULL;
    vcErrore                            varchar(4000);
      vcStato                             varchar(10); -- (N)ormale / (W)arning / (E)rrore / (NA) Non Eseguito
      idProcedura                         numeric := 0;
      codProcedura                        varchar(50) := 'POST_DM_UPDT_VEND_CUST_SERV';

    v_state   TEXT;
    v_msg     TEXT;
    v_detail  TEXT;
    v_hint    TEXT;
    v_context TEXT; 

 ANNOMESE RECORD;

begin
    

IF(p_flg_init='Y')
then
begin
   
   proc_step := 'LOOP ANNOMESE';
   BEGIN
   FOR ANNOMESE 
    IN (
         SELECT
               mf_id  FROM d_tempo WHERE mf_id
               BETWEEN To_Char(current_date-1+interval '-24 month','YYYYMM')::integer and  To_Char(current_date-1+interval '-1 month','YYYYMM')::integer              
           
  -- intervallo rolling 12 mese chiuso

       )
   LOOP
      statement in loop         ;
   END LOOP;  
end;
else
begin
statement that not use lopp    ;
end;
end if; 


  
  
  
  
END;
$function$
;

当我编译代码时,错误:SQL 错误 [42601]:错误:语法错误在“else”或附近 位置:5669 出现。 如果我在不使用 else 的情况下编写函数,它可以正常工作

PostgreSQL 函数

评论


答:

0赞 Pavel Stehule 11/13/2023 #1

主要问题是前面缺少关键字。这不是 Pascal 语言,你不需要到处使用显式块。请先尝试阅读文档ENDELSE

您的代码(错误):

IF x THEN
BEGIN
  RAISE NOTICE 'hello';
  a := a + 1;
END;
ELSE
BEGIN
  RAISE NOTICE 'Hi';
  a := a + 2;
END;
END IF;

正确版本:

IF x THEN
  RAISE NOTICE 'hello';
  a := a + 1;
ELSE
  RAISE NOTICE 'Hi';
  a := a + 2;
END IF;
1赞 Samuele 11/13/2023 #2

我已经删除了开始和结束,现在我在异常中有不同的错误:错误:语法错误在“异常”或附近 第 281 行:异常

CREATE OR REPLACE FUNCTION dwh.f_dwh_post_dm_updt_vend_cust_serv(p_flg_init varchar DEFAULT 'N')
 RETURNS void
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$
DECLARE

   proc_step       varchar := NULL; 
   nTemId     numeric := NULL;
   qta_nobilia numeric := NULL;
    vcErrore                            varchar(4000);
      vcStato                             varchar(10); -- (N)ormale / (W)arning / (E)rrore / (NA) Non Eseguito
      idProcedura                         numeric := 0;
      codProcedura                        varchar(50) := 'POST_DM_UPDT_VEND_CUST_SERV';

    v_state   TEXT;
    v_msg     TEXT;
    v_detail  TEXT;
    v_hint    TEXT;
    v_context TEXT; 

 ANNOMESE RECORD;

begin 
    
update dwh.semaforo_cust_service
set flag_semaforo='WIP';

-- ######################################################################################
-- Log esecuzione procedura - INIZIO
-- ######################################################################################
     SELECT nextval('seq_log_proc') INTO  idProcedura;
     INSERT INTO dwh_ods.adm_log_procedure(ID_LOG, COD_PROCEDURA, DAT_INIZIO, DAT_FINE, COD_STATO, DES_LOG)
     VALUES (idProcedura, codProcedura, clock_timestamp(), NULL, 'RUN', '');

      vcStato := 'NE';

-- ######################################################################################
-- Step #0: Valorizzazioen TEM_ID
-- ######################################################################################
     IF nTemID IS NULL THEN
        SELECT MIN((TO_CHAR(CFG_DT_INF, 'YYYYMM'))::numeric )
        INTO   nTemID
        FROM   dwh_ep.sys_wkt_periodi_temporali
        WHERE  CFG_COD = 'M-1'
               AND PARTKEY < 'p004';
IF(p_flg_init='Y')
then

   -- SB 17/10/2023  : Script che aggiorna le tabelle di appoggio per il report quality del customer servcie
   truncate table dwh.venduto_per_customer_service;
  

   
   proc_step := 'LOOP ANNOMESE';
   begin 
   FOR ANNOMESE 
    IN (
         SELECT
               mf_id  FROM d_tempo WHERE mf_id
               BETWEEN To_Char(current_date-1+interval '-24 month','YYYYMM')::integer and  To_Char(current_date-1+interval '-1 month','YYYYMM')::integer              
           
  -- intervallo rolling 12 mese chiuso

       )
   LOOP
      loop statement         ;
   END LOOP;  
  end;
else
no loop statement       ;
end if; 

/* effettuo il merge per rimpiere i buchi dove articolo non viene portato avanti nel dwh */



-- ######################################################################################
-- ######################################################################################
      vcStato := 'N';

  -- ######################################################################################
-- Log esecuzione procedura - FINE OK
-- ######################################################################################
     UPDATE dwh_ods.adm_log_procedure
     SET    DAT_FINE    = clock_timestamp()
            , COD_STATO = vcStato
            , DES_LOG   = nTemID::varchar|| ' - Terminazione Corretta.'
     WHERE  ID_LOG = idProcedura;
     update dwh.semaforo_cust_service
   set flag_semaforo='OK';
    
  EXCEPTION
     WHEN OTHERS THEN
          --vcErrore := SUBSTR('EXCEPTION: SQLCODE = ' || SQLSTATE::varchar || ' - SQLERRM = ' || SQLERRM, 1, 4000);

            GET STACKED DIAGNOSTICS
                    v_state   = RETURNED_SQLSTATE,
                    v_msg     = MESSAGE_TEXT,
                    v_detail  = PG_EXCEPTION_DETAIL,
                    v_hint    = PG_EXCEPTION_HINT,
                    v_context = PG_EXCEPTION_CONTEXT; 
                
          vcErrore := SUBSTR('EXCEPTION: SQLCODE = ' || v_state || ' - SQLERRM = ' || v_msg, 1, 4000);
          vcStato := 'E';

-- ######################################################################################
-- Log esecuzione procedura - FINE KO
-- ######################################################################################
     UPDATE dwh_ods.adm_log_procedure
     SET    DAT_FINE    = clock_timestamp()
            , COD_STATO = vcStato
            , DES_LOG   = SUBSTR(nTemID::varchar || ' - ' || coalesce(DES_LOG, ' ') || vcErrore, 1, 512)
     WHERE  ID_LOG = idProcedura;
    update dwh.semaforo_cust_service
   set flag_semaforo='KO';
  
  
end ;
$function$;

评论

0赞 Samuele 11/14/2023
我已经解决了..如果在这句话的末尾,有一个缺失的结局......不幸的是,引发的错误可能会被误解: 如果 nTemID 为 NULL,则选择 MIN((TO_CHAR(CFG_DT_INF, 'YYYYMM'))::NUMERIC ) INTO nTemID FROM dwh_ep.sys_wkt_periodi_temporali WHERE CFG_COD = 'M-1' AND PARTKEY < 'p004';