Некоторая синтаксическая ошибка - не могу понять где
Вот сценарий, который я написал, и он имеет странную синтаксическую ошибку в блоке 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 ответ
Похоже, ошибка в том, что ваше предложение 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;