Некоторая синтаксическая ошибка - не могу понять где - PullRequest
2 голосов
/ 18 февраля 2011

Вот сценарий, который я написал, и у него странная синтаксическая ошибка в блоке EXCEPTION.Если я удаляю блок исключения, скрипт компилируется правильно.но как только я пишу это обратно, это дает мне ошибку

Error(58,11): PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:     ( begin case declare else elsif end exit for goto if loop mod    null pragma raise return select update while with    <an identifier> <a double-quoted delimited-identifier>    <a bind variable> << continue close current delete fetch lock    insert open rollback savepoint set sql execute commit forall    merge pipe purge 

Вот сценарий

LOOP
  BEGIN
    SAVEPOINT check_point;

    EXIT WHEN DBMS_SQL.FETCH_ROWS (cursor_handle) = 0;
    DBMS_SQL.COLUMN_VALUE (cursor_handle, 1,  cc , col_err, actual_len);
    DBMS_SQL.COLUMN_VALUE (cursor_handle, 2,  di, col_err, actual_len);

    IF INSTR (cc, '_') <> 0 THEN
      cc := Trim (cc);
      cc := Upper(cc);
      cc := substr(cc,4,2);

      EXECUTE IMMEDIATE 'UPDATE  ' || dest || ' SET cc = :v1 WHERE di = :v2' 
        USING cc, di;

      if SQL%ROWCOUNT > 0 THEN
        inserts := inserts + 1;
        counter := counter + 1;
        IF counter > 500 THEN
          counter := 0;
          COMMIT;
        END IF;
      END IF;

      EXCEPTION
        WHEN DUP_VAL_ON_INDEX THEN
          dups := dups+1;
          ROLLBACK TO check_point;
        WHEN VALUE_ERROR THEN
          valerr := valerr +1;
          ROLLBACK TO check_point;
        WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE('errno: ' || TO_CHAR(SQLCODE) || ' Msg: ' || SQLERRM);
          otherexc := otherexc +1;
        IF otherexc > 50 THEN 
          EXIT;
        END IF;
        ROLLBACK TO check_point;              
    END IF;
  END;
END LOOP;

Я знаю, что очень неприятно задавать такой вопрос, но я не могу понятьчто это за ошибкаЯ специалист по PL / SQL.

1 Ответ

3 голосов
/ 18 февраля 2011

Похоже, ошибка в том, что ваше предложение EXCEPTION находится внутри операторов IF INSTR (cc, '_') <> 0 IF, но вы хотите сопоставить EXCEPTION с оператором BEGIN в верхней части цикла. Я полагаю, что вы хотите перейти END IF; за IF INSTR (cc, '_') <> 0 до ИСКЛЮЧЕНИЯ, как я делаю здесь

LOOP
  BEGIN
    SAVEPOINT check_point;

    EXIT WHEN DBMS_SQL.FETCH_ROWS (cursor_handle) = 0;
    DBMS_SQL.COLUMN_VALUE (cursor_handle, 1,  cc , col_err, actual_len);
    DBMS_SQL.COLUMN_VALUE (cursor_handle, 2,  di, col_err, actual_len);

    IF INSTR (cc, '_') <> 0 THEN
      cc := Trim (cc);
      cc := Upper(cc);
      cc := substr(cc,4,2);

      EXECUTE IMMEDIATE 'UPDATE  ' || dest || ' SET cc = :v1 WHERE di = :v2' 
        USING cc, di;

      if SQL%ROWCOUNT > 0 THEN
        inserts := inserts + 1;
        counter := counter + 1;
        IF counter > 500 THEN
          counter := 0;
          COMMIT;
        END IF; -- IF counter > 500
      END IF; -- IF SQL%ROWCOUNT > 0
    END IF; -- INSTR (cc, '_') <> 0


  EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
      dups := dups+1;
      ROLLBACK TO check_point;
    WHEN VALUE_ERROR THEN
      valerr := valerr +1;
      ROLLBACK TO check_point;
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('errno: ' || TO_CHAR(SQLCODE) || ' Msg: ' || SQLERRM);
      otherexc := otherexc +1;
      IF otherexc > 50 THEN 
        EXIT;
      END IF;
      ROLLBACK TO check_point;              
  END;
END LOOP;

При этом, однако, я бы, вероятно, немного переписал код. Фиксация каждые 500 строк почти наверняка является ошибкой. Я очень сомневаюсь в вашем обработчике исключений WHEN OTHERS - я бы действительно подумал, что вы хотите хотя бы записать ошибку в таблицу или заполнить коллекцию ошибок, а не записывать в буфер DBMS_OUTPUT, который может или не может быть будет отображаться.

LOOP
  SAVEPOINT check_point;

  EXIT WHEN DBMS_SQL.FETCH_ROWS (cursor_handle) = 0;
  DBMS_SQL.COLUMN_VALUE (cursor_handle, 1,  cc , col_err, actual_len);
  DBMS_SQL.COLUMN_VALUE (cursor_handle, 2,  di, col_err, actual_len);

  IF INSTR (cc, '_') <> 0 THEN
    cc := Trim (cc);
    cc := Upper(cc);
    cc := substr(cc,4,2);

    BEGIN
      EXECUTE IMMEDIATE 'UPDATE  ' || dest || ' SET cc = :v1 WHERE di = :v2' 
        USING cc, di;

      if SQL%ROWCOUNT > 0 THEN
        inserts := inserts + 1;
      END IF; 
    EXCEPTION
      WHEN DUP_VAL_ON_INDEX THEN
        dups := dups+1;
        ROLLBACK TO check_point;
      WHEN VALUE_ERROR THEN
        valerr := valerr +1;
        ROLLBACK TO check_point;
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('errno: ' || TO_CHAR(SQLCODE) || ' Msg: ' || SQLERRM);
        otherexc := otherexc +1;
        IF otherexc > 50 THEN 
          EXIT;
        END IF;
        ROLLBACK TO check_point;              
    END;

  END IF; -- INSTR (cc, '_') <> 0
END LOOP;
...