【问题标题】:Oracle function compilation error PLS-00103 (Encountered the symbol "SELECT" ...)Oracle函数编译错误PLS-00103(遇到符号“SELECT”...)
【发布时间】:2016-02-08 22:06:25
【问题描述】:

我在编译这个函数时收到以下错误:

PROCEDURE INV.USP_MSC_MODIFICA_ESTADO 的编译错误

Error: PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:( - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
 continue avg count current exists max min prior sql stddev
sum variance execute forall merge time timestamp interval
date <a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set specification>
<an alternat    Line: 14    Text: IF SELECT TRUNC((SYSDATE) -TO_DATE(@FCH_GRABACION, 'DD/MM/YYYY HH24:MI:SS')) From DUAL=1 THEN
CREATE OR REPLACE PROCEDURE "USP_MSC_MODIFICA_ESTADO" AS
  BEGIN
    DECLARE
      CURSOR reservar IS
      SELECT
        id_reserva,
        fch_grabacion 
       FROM tb_msc_reserva
      WHERE to_date(to_char(fch_grabacion, 'dd/mm/yyyy')) = to_date(to_char(SYSDATE, 'dd/mm/yyyy')) - 1;
      id_reserva    VARCHAR2(50);
      fch_grabacion DATE;
    BEGIN
      OPEN reservar;
      FETCH reservar INTO id_reserva, fch_grabacion;

      IF SELECT TRUNC((SYSDATE) - TO_DATE(@fch_grabacion, 'DD/MM/YYYY HH24:MI:SS')) FROM dual=1 THEN

      UPDATE inv.tb_msc_reserva t
      SET t.flg_estado = 'C'
      WHERE id_reserva = @id_reserva;
      COMMIT;
    END if;
    WHILE (@@fetch_status = 0)

    CLOSE RESERVAR;

  END;

【问题讨论】:

  • 哇,这简直是一团糟。对不起。这不是 sql-server,因此您可能需要花一些时间阅读pl/sql documenation
  • 如果fch_grabaciondate,你为什么要先写to_char,然后再写to_date?为什么你在sysdate 上做同样的事情?如果您的查询已经检查 fch_grabacion 的日期部分比 sysdate 的日期部分晚 1 天,为什么要单独使用 IF 语句再次检查它?如果您想这样做,则不需要select,但该声明本身毫无意义。您不要使用 @ 为局部变量添加前缀。您不想为与列名冲突的局部变量使用名称。您可以在一个 update 中完成所有操作而无需循环。

标签: oracle syntax plsql compiler-errors pls-00103


【解决方案1】:

Franky 说代码中有太多错误。写不完。 几个错误:

  1. 不需要在第 4 行声明。
  2. Begin 语句过多。
  3. 虽然 (@@FETCH_STATUS=0) 不用于循环终止。使用 EXIT WHEN。
  4. 错过了循环开始和结束循环[假设您使用的是循环,因为您是光标而不是选择进入]

    CREATE OR REPLACE PROCEDURE "USP_MSC_MODIFICA_ESTADO"
    AS
    CURSOR reservar
    IS
    SELECT id_reserva, fch_grabacion
    FROM tb_msc_reserva
    WHERE TO_DATE (TO_CHAR (fch_grabacion, 'dd/mm/yyyy')) =
    TO_DATE (TO_CHAR (SYSDATE, 'dd/mm/yyyy'))
    - 1;
    
    id_reserva      VARCHAR2 (50);
    fch_grabacion   DATE;
    BEGIN
    OPEN reservar;
    
    FETCH reservar
    INTO id_reserva, fch_grabacion;
    
    LOOP
    IF (SELECT TRUNC (  (SYSDATE) - TO_DATE (@fch_grabacion, 'DD/MM/YYYY HH24:MI:SS'))
    FROM DUAL) = 1
    THEN
    UPDATE inv.tb_msc_reserva t
    SET t.flg_estado = 'C'
    WHERE id_reserva = @id_reserva;
    
    COMMIT;
    END IF;
    
    EXIT WHEN (@@fetch_status = 0);
    END LOOP;
    
    CLOSE reservar;
    END;
    

【讨论】:

    【解决方案2】:

    我很抱歉,但我真的是 Oracle 的新手。我已经更改了代码,但我一直收到同样的错误。

    CREATE OR REPLACE PROCEDURE "USP_MSC_MODIFICA_ESTADO"
    AS
    CURSOR reservar
    IS 
    SELECT id_reserva, fch_grabacion
    FROM tb_msc_reserva
    WHERE to_date(FCH_GRABACION,'dd/mm/yyyy') =  to_date(SYSDATE,'dd/mm/yyyy')-  1;
    
    reserva      VARCHAR2 (50);
    fch_grabacion   DATE;
    BEGIN
    OPEN reservar;
    FETCH reservar
    INTO reserva, fch_grabacion;
    
    LOOP
    IF (SELECT TRUNC((SYSDATE) -TO_DATE(fch_grabacion, 'DD/MM/YYYY HH24:MI:SS'))From DUAL=1)
    
    THEN
    UPDATE inv.tb_msc_reserva t
    SET t.flg_estado = 'C'
    WHERE id_reserva = reserva;
    
    COMMIT;
    END IF;
    
    EXIT WHEN reservar%NOTFOUND ;
    END LOOP;
    
    CLOSE reservar;
    END;
    

    我想做的是比较两个日期(dd/mm/yyyy HH:mm:ss)。 (昨天和今天)如果我的注册表超过 24 小时,那么 ID_ESTADO='C'

    我这里有错误:

     IF (SELECT TRUNC((SYSDATE) -TO_DATE(fch_grabacion, 'DD/MM/YYYY  HH24:MI:SS'))   From DUAL=1)
    

    消息:

     Compilation errors for PROCEDURE INV.USP_MSC_MODIFICA_ESTADO
    Error: PLS-00103: Encountered the symbol "SELECT" when expecting one of  the following:
    
      ( - + case mod new not null <an identifier>
      <a double-quoted delimited-identifier> <a bind variable>
      continue avg count current exists max min prior sql stddev
      sum variance execute forall merge time timestamp interval
      date <a string literal with character set specification>
      <a number> <a single-quoted SQL string> pipe
      <an alternatively-quoted string literal with character set  specification>
       <an alternat
     Line: 18
     Text: IF (SELECT TRUNC((SYSDATE) -TO_DATE(fch_grabacion, 'DD/MM/YYYY    HH24:MI:SS')) From DUAL=1)
    
     Error: PLS-00103: Encountered the symbol "=" when expecting one of the   f       oollowing:
    
      . , @ ; for <an identifier>
      <a double-quoted delimited-identifier> group having intersect
      minus order partition start subpartition union where connect
      sample
    Line: 18
    Text: IF (SELECT TRUNC((SYSDATE) -TO_DATE(fch_grabacion, 'DD/MM/YYYY        HH24:MI:SS')) From DUAL=1)
    

    谢谢

    【讨论】:

      【解决方案3】:

      你的代码的问题是你在 Select 子句中使用了与 1 的比较。 你的代码:

      IF (SELECT TRUNC((SYSDATE) -TO_DATE(fch_grabacion, 'DD/MM/YYYY HH24:MI:SS'))From DUAL=1)
      

      更正的代码:

      IF (SELECT TRUNC (  (SYSDATE) - TO_DATE (fch_grabacion, 'DD/MM/YYYY HH24:MI:SS')) FROM DUAL) = 1
      

      但是,有更好的方法来比较 24 小时时差[我在这里感到困惑,因为你是指 1 天时差还是 24 小时时差]: 1.如果要比较24小时:

      IF TO_DATE (fch_grabacion, 'DD/MM/YYYY HH24:MI:SS') < (SYSDATE - 1)
      

      2。如果你想比较一维:

      IF TO_DATE (fch_grabacion, 'DD/MM/YYYY') < TRUNC ((SYSDATE - 1))
      

      希望这会有所帮助。如果是这样。不要忘记将此答案标记为已接受并投票。[我可以做一些额外的代表:p]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        • 2019-04-29
        • 2020-09-10
        • 2018-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多