如果..在Oracle中不起作用

时间:2016-03-15 12:03:21

标签: oracle if-statement stored-procedures plsql

我编写了一个包含简单if..else if..end的过程,如下所示。 编译时会抛出错误

  

错误(103,8):PLS-00103:遇到以下其中一项时遇到符号“LOOP”:if   错误(113,4):PLS-00103:遇到以下其中一项时遇到符号“end-of-file”:end not pragma final instantiable order overriding static member constructor map

我无法找到错误原因,因为我认为我已正确关闭所有IF。任何人都可以帮助。以下是我的整个程序

CREATE OR REPLACE PROCEDURE proc_ntitems_update
AS
   CURSOR cur_systeminfo
   IS
      SELECT location,
             childseq,
             btproduct,
             product,
             questionid
        FROM systeminfo;

   vproduct         tblsysteminfo_products.product%TYPE;
   vquestionid      tblsysteminfo_products.questionid%TYPE;
   vlocation        systeminfo.location%TYPE;
   vchildseq        systeminfo.childseq%TYPE;
   verror           VARCHAR2 (200);
   consrgsitename   VARCHAR2 (100);
   consrgsite       VARCHAR2 (100);
   conmgsitename    VARCHAR2 (100);
   intname          NUMBER;
   vsicount         NUMBER;
BEGIN
   OPEN cur_systeminfo;

   LOOP
      FETCH cur_systeminfo
      INTO vlocation, vchildseq, vbtproduct, vproduct, vquestionid;

      EXIT WHEN cur_systeminfo%NOTFOUND;

      IF INSTR (vlocation, '_') > 0
      THEN
         vquestionid := consrgsitename;

         IF SUBSTR (vlocation, 1, LENGTH (consrgsite)) = consrgsite
         THEN
            intname := LENGTH (consrgsite);
            vquestionid := consrgsitename;
         ELSE
            IF SUBSTR (vlocation, 1, LENGTH (consrg50site)) = consrg50site
            THEN
               intname := LENGTH (consrgsite);
               vquestionid := consrgsitename;
               vlocation :=
                     vlocation
                  || SUBSTR (vlocation, intname + 1, LENGTH (vlocation));
            --Check if this item is for a DATA site. These have a Location of locations_data_n where n is  the site number.

            ELSE
               IF LOWER (SUBSTR (vlocation, 1, 14)) = 'locations_data'
               THEN
                  vsitename := 'Yes';
                  vquestionid := 'txtLocationName';
               ELSE
                  IF     LOWER (SUBSTR (vlocation, 1, 14)) = 'locations_data'
                     AND vchildseq = '0'
                  THEN
                     BEGIN
                        SELECT COUNT (location)
                          INTO vsicount
                          FROM systeminfo
                         WHERE LOWER (vlocation) = 'locations_1';
                     EXCEPTION
                        WHEN nodatafound
                        THEN
                           verror :=
                                 ' proc_ntitems_update '
                              || SUBSTR (
                                    TO_CHAR (SQLCODE) || ' - ' || SQLERRM,
                                    1,
                                    480);
                        WHEN OTHERS
                        THEN
                           verror :=
                                 ' proc_ntitems_update '
                              || SUBSTR (
                                    TO_CHAR (SQLCODE) || ' - ' || SQLERRM,
                                    1,
                                    480);
                     END;

                     IF vsicount = 0
                     THEN
                        vsitename := 'No';
                        intname := LENGTH (vlocation);
                        vquestionid := 'txtLocationName';
                     END IF;
                  ELSE
                     IF     LOWER (SUBSTR (vlocation, 1, 14)) =
                               'locations_data'
                        AND vchildseq > '0'
                     THEN
                        vquestionid := 'txtLocationName';
                     ELSE
                        IF LOWER (SUBSTR (vlocation, 1, 5)) = 'ripe_'
                        THEN
                           vremotesitenumber :=
                              SUBSTR (
                                 vlocation,
                                 -1,
                                 (LENGTH (vloaction) - INSTR (vlocation, '_')));
                           vproduct := 'MMRemote';
                           vquestionid := 'cboRemoteType' || vremotesitenumber;
                           vsitename := vecvalue || ' ' || vremotesitenumber;
                        ELSE
                           IF LOWER (
                                 SUBSTR (vlocation,
                                         1,
                                         LENGTH (conmerchandisesite))) =
                                 conmerchandisesite
                           THEN
                              vsitename := conmerchandisesite;
                           ELSE
                              vsitename := btproduct;
                           END IF;


                           BEGIN
                              UPDATE tblntitems
                                 SET location = vlocation,
                                     childseq = vchildseq,
                                     sitename = vbtproduct,
                                     product = vproduct,
                                     questionid = vquestionid
                               WHERE questionid = vquestionid;
                           EXCEPTION
                              WHEN OTHERS
                              THEN
                                 verror :=
                                       'proc_ntitems_update '
                                    || SUBSTR (
                                             TO_CHAR (SQLCODE)
                                          || ' - '
                                          || SQLERRM,
                                          1,
                                          480);
                           END;
                        END IF;
                     END loop;

   CLOSE   cur_systeminfo;

      EXCEPTION
        WHEN OTHERS
        THEN
              verror := 'proc_ntitems_update ' || substr (to_char (sqlcode) || ' - ' || sqlerrm, 1, 480);

        INSERT INTO log_import_errors VALUES ('sysdate', verror);
END;

1 个答案:

答案 0 :(得分:2)

您正在创建嵌套的if-then-else语句;您在同一行上有ELSEIF,但它们是不同的控制级别。如果安排缩进以显示嵌套,可能更容易理解你出错的地方,如:

LOOP
  ...
  IF Instr(Vlocation,'_') >0 THEN
    ...
    IF SUBSTR(Vlocation,1,LENGTH(Consrgsite)) = Consrgsite THEN
      ...
    ELSE
      IF SUBSTR(Vlocation,1,LENGTH(Consrg50site)) = Consrg50site THEN
        ...
      ELSE
        IF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' THEN
          ...
        ELSE
          IF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' AND Vchildseq = '0' THEN
            ...
            IF Vsicount = 0 THEN
              ...
            END IF;
          ELSE
            IF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' AND Vchildseq > '0' THEN
              ...
            ELSE
              IF Lower(SUBSTR(Vlocation,1,5)) = 'ripe_' THEN
                ...
              ELSE
                IF Lower(SUBSTR(Vlocation,1,LENGTH(Conmerchandisesite))) = Conmerchandisesite THEN
                  ...
                ELSE
                  ...
                END IF;
                ...
              END IF;
            END LOOP;

您当前有END LOOP的位置,它希望看到与END IF行匹配的IF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' AND Vchildseq > '0' THEN

正如Tony Andrews在评论中所说,你需要END IF来匹配每个IF。您目前有六个级别的控件,使用IF打开但未使用END IF关闭。

您似乎期望它像ELSIF一样工作,您可以使用它来代替:

LOOP
  ...
  IF Instr(Vlocation,'_') >0 THEN
    ...
    IF SUBSTR(Vlocation,1,LENGTH(Consrgsite)) = Consrgsite THEN
      ...
    ELSIF SUBSTR(Vlocation,1,LENGTH(Consrg50site)) = Consrg50site THEN
      ...
    ELSIF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' THEN
      ...
    ELSIF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' AND Vchildseq = '0' THEN
      ...
      IF Vsicount = 0 THEN
        ...
      END IF;
    ELSIF Lower(SUBSTR(Vlocation,1,14)) = 'locations_data' AND Vchildseq > '0' THEN
      ...
    ELSIF Lower(SUBSTR(Vlocation,1,5)) = 'ripe_' THEN
      ...
    ELSIF Lower(SUBSTR(Vlocation,1,LENGTH(Conmerchandisesite))) = Conmerchandisesite THEN
      ...
    ELSE
      ...
    END IF;
  ...
  END IF;
END LOOP;

您也可以使用searched CASE expression代替if-then-elsif-else,但效果相同。

详细了解conditional control statements