功能触发:遇到符号“BEGIN”?

问题描述 投票:1回答:2

相对新手在这里。我有一个3部分任务,似乎无法正确填充最后一部分。我试图使用2个函数输出平均客人数(有效)和预订晚数(不工作)。

以下是这两部分的工作代码:

        SQL> DECLARE
  2     DDI_REC    DDI.LEDGER_VIEW %ROWTYPE;           --declaring DDI_REC
  3     DDI_ROOM   DDI.LEDGER_VIEW.ROOMNUM%type := 0;  --declaring DDI_ROOM and assiging it to ZERO
  4     FOUND_ROWS BOOLEAN := FALSE;               --variable to test for no_data_found exception in the FOR LOOP
  5  
  6      FUNCTION AVG_GUESTS(ROOM IN NUMBER)
  7          RETURN NUMBER
  8      AS AVERAGE NUMBER;
  9  
 10      BEGIN
 11          SELECT AVG(ADULTCNT + CHILDCNT)
 12          INTO AVERAGE
 13          FROM DDI.LEDGER_VIEW
 14          WHERE ROOMNUM = ROOM;
 15  
 16          RETURN AVERAGE;
 17  
 18          EXCEPTION
 19           WHEN OTHERS THEN
 20           RETURN NULL;
 21       END;
 22  
 23  
 24      BEGIN
 25          DBMS_OUTPUT.NEW_LINE;
 26          DBMS_OUTPUT.PUT_LINE ('      AVG ROOM RENTALS');
 27          DBMS_OUTPUT.PUT_LINE ('     PER DDI.LEDGER_VIEW');
 28          DBMS_OUTPUT.NEW_LINE;
 29          DBMS_OUTPUT.PUT_LINE ('  ROOM  AVG NUMBER  BOOKED');
 30          DBMS_OUTPUT.PUT_LINE ('   NUM   OF GUESTS  NIGHTS');
 31          DBMS_OUTPUT.PUT_LINE ('  ----  ----------  ------');
 32  
 33          -- LOOP CALLS FUNCTION AVG_GUESTS ON EACH CHANGE IN ROOMNUM
 34  
 35          FOR DDI_REC IN
 36              (SELECT *
 37               FROM DDI.LEDGER_VIEW
 38               ORDER BY ROOMNUM)
 39              LOOP
 40                  FOUND_ROWS := TRUE;     --if data exist, sets variable to TRUE, so IF statement doesn't run
 41                  IF  DDI_ROOM != DDI_REC.ROOMNUM THEN
 42                      DDI_ROOM := DDI_REC.ROOMNUM;
 43                      DBMS_OUTPUT.PUT_LINE('   ' ||DDI_ROOM||'    '||TO_CHAR(AVG_GUESTS(DDI_ROOM), '9.99'));
 44                  END IF;
 45              END LOOP;  -- End of loop
 46  
 47  
 48          IF NOT FOUND_ROWS THEN      -- trigger the exception below when no results are returned
 49              RAISE NO_DATA_FOUND;
 50          END IF;
 51  
 52  EXCEPTION
 53          WHEN NO_DATA_FOUND THEN
 54              DBMS_OUTPUT.PUT_LINE('No data found.');
 55  END;
 56  /

      AVG ROOM RENTALS                                                          
     PER DDI.LEDGER_VIEW                                                        

  ROOM  AVG NUMBER  BOOKED                                                      
   NUM   OF GUESTS  NIGHTS                                                      
  ----  ----------  ------                                                      
   101     1.00                                                                 
   102     2.00                                                                 
   103     2.14                                                                 
   104     2.17                                                                 
   105     2.40                                                                 
   106     1.75                                                                 
   107     1.67                                                                 
   108     1.80                                                                 

PL/SQL procedure successfully completed.

现在破碎的代码,因为我试图让“预订的夜晚”工作。我甚至可能在错误的树上吠叫如何去做。

    SQL> DECLARE
  2     DDI_REC    DDI.LEDGER_VIEW %ROWTYPE;        --declaring DDI_REC
  3     DDI_ROOM   DDI.LEDGER_VIEW.ROOMNUM%type := 0;   --declaring DDI_ROOM and assiging it to ZERO
  4     FOUND_ROWS BOOLEAN := FALSE;            --variable to test for no_data_found exception in the FOR LOOP
  5     BOOKED_ROOMS DDI.LEDGER_VIEW.ROOMNUM%type := 0; --declaring BOOKED_ROOMS
  6  
  7      FUNCTION AVG_GUESTS(ROOM IN NUMBER)
  8          RETURN NUMBER
  9      AS AVERAGE NUMBER;
 10  
 11      BEGIN
 12          SELECT AVG(ADULTCNT + CHILDCNT)
 13          INTO AVERAGE
 14          FROM DDI.LEDGER_VIEW
 15          WHERE ROOMNUM = ROOM;
 16  
 17          RETURN AVERAGE;
 18  
 19          EXCEPTION
 20           WHEN OTHERS THEN
 21           RETURN NULL;
 22       END;
 23  
 24      BEGIN
 25         SELECT COUNT(*)
 26         FROM DDI.LEDGER_VIEW
 27         WHERE ROOMNUM = BOOKED_ROOMS;
 28  
 29         EXCEPTION
 30           WHEN OTHERS THEN
 31           RETURN NULL;
 32       END;
 33  
 34  
 35      BEGIN
 36          DBMS_OUTPUT.NEW_LINE;
 37          DBMS_OUTPUT.PUT_LINE ('      AVG ROOM RENTALS');
 38          DBMS_OUTPUT.PUT_LINE ('     PER DDI.LEDGER_VIEW');
 39          DBMS_OUTPUT.NEW_LINE;
 40          DBMS_OUTPUT.PUT_LINE ('  ROOM  AVG NUMBER  BOOKED');
 41          DBMS_OUTPUT.PUT_LINE ('   NUM   OF GUESTS  NIGHTS');
 42          DBMS_OUTPUT.PUT_LINE ('  ----  ----------  ------');
 43  
 44          -- LOOP CALLS FUNCTION AVG_GUESTS ON EACH CHANGE IN ROOMNUM
 45  
 46          FOR DDI_REC IN
 47              (SELECT *
 48               FROM DDI.LEDGER_VIEW
 49               ORDER BY ROOMNUM)
 50              LOOP
 51                  FOUND_ROWS := TRUE;     --if data exist, sets variable to TRUE, so IF statement doesn't run
 52                  IF  DDI_ROOM != DDI_REC.ROOMNUM THEN
 53                      DDI_ROOM := DDI_REC.ROOMNUM;
 54                      DBMS_OUTPUT.PUT_LINE('   ' ||DDI_ROOM||'    '||TO_CHAR(AVG_GUESTS(DDI_ROOM), '9.99')|| '  '||TO_CHAR(BOOKED_ROOMS));
 55                  END IF;
 56              END LOOP;  -- End of loop
 57  
 58  
 59          IF NOT FOUND_ROWS THEN      -- trigger the exception below when no results are returned
 60              RAISE NO_DATA_FOUND;
 61        END IF;
 62  
 63  EXCEPTION
 64          WHEN NO_DATA_FOUND THEN
 65              DBMS_OUTPUT.PUT_LINE('No data found.');
 66  END;
 67  /
    BEGIN
    *
ERROR at line 35:
ORA-06550: line 35, column 5: 
PLS-00103: Encountered the symbol "BEGIN"

任何和所有建议欢迎...提前谢谢你。

oracle function plsql
2个回答
0
投票

我重新格式化了你的代码并添加了BEGIN-END outmost block(缺少了)以及一些注释。看一看。

DECLARE
  ddi_rec        ddi.ledger_view%rowtype;        --declaring DDI_REC
  ddi_room       ddi.ledger_view.roomnum%TYPE := 0;   --declaring DDI_ROOM and assiging it to ZERO
  found_rows     BOOLEAN := false;            --variable to test for no_data_found exception in the FOR LOOP
  booked_rooms   ddi.ledger_view.roomnum%TYPE := 0; --declaring BOOKED_ROOMS

  FUNCTION avg_guests (
    room IN NUMBER
  ) RETURN NUMBER AS
    average   NUMBER;
  BEGIN
    SELECT AVG(adultcnt + childcnt) INTO
      average
    FROM ddi.ledger_view
    WHERE roomnum = room;

    RETURN average;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END;

BEGIN  --> you miss this outmost BEGIN ...
  -- the 1st begin-exception-end block has to be part of the outmost begin-end
  BEGIN
    SELECT COUNT(*)
    FROM ddi.ledger_view
    WHERE roomnum = booked_rooms;

  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END;  -- the 1st block ends here

  -- the 2nd begin-exception-end block begins here
  BEGIN
    dbms_output.new_line;
    dbms_output.put_line('      AVG ROOM RENTALS');
    dbms_output.put_line('     PER DDI.LEDGER_VIEW');
    dbms_output.new_line;
    dbms_output.put_line('  ROOM  AVG NUMBER  BOOKED');
    dbms_output.put_line('   NUM   OF GUESTS  NIGHTS');
    dbms_output.put_line('  ----  ----------  ------');

           -- LOOP CALLS FUNCTION AVG_GUESTS ON EACH CHANGE IN ROOMNUM
    FOR ddi_rec IN ( SELECT * FROM ddi.ledger_view
    ORDER BY roomnum ) LOOP
      found_rows := true;     --if data exist, sets variable to TRUE, so IF statement doesn't run
      IF
        ddi_room != ddi_rec.roomnum
      THEN
        ddi_room := ddi_rec.roomnum;
        dbms_output.put_line('   '
        || ddi_room
        || '    '
        || TO_CHAR(avg_guests(ddi_room),'9.99')
        || '  '
        || TO_CHAR(booked_rooms) );

      END IF;

    END LOOP;  -- End of loop

    IF
      NOT found_rows
    THEN      -- trigger the exception below when no results are returned
      RAISE no_data_found;
    END IF;
  EXCEPTION
    WHEN no_data_found THEN
      dbms_output.put_line('No data found.');
  END;  -- the 2nd begin-exception-end block ends here

END;  --> ... and you miss this END, for the outmost begin-end block
/

0
投票

我看到两个问题。你的主体有两个BEGIN积木。我相信Littlefoot纠正了这一点。也:

 25         SELECT COUNT(*)
 26         FROM DDI.LEDGER_VIEW
 27         WHERE ROOMNUM = BOOKED_ROOMS;

在计数(*)之后需要一个INTO子句。您需要将值选择到变量中并对变量执行某些操作。你不能在PL / SQL中使用裸SELECT,就像在sqlplus命令行中一样。

© www.soinside.com 2019 - 2024. All rights reserved.