Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何回滚到循环中的下一个迭代?_Sql_Database_Oracle_Exception_Plsql - Fatal编程技术网

Sql 如何回滚到循环中的下一个迭代?

Sql 如何回滚到循环中的下一个迭代?,sql,database,oracle,exception,plsql,Sql,Database,Oracle,Exception,Plsql,为了更容易地解释我的问题,我将粘贴我的全部代码: drop table tst; create table tst (t1 number(2)); set serveroutput on DECLARE TYPE vltp IS TABLE OF NUMBER(3); vl vltp := vltp(2,12,33,344,55,66,7,555,4); NUMBER_TO_BIG EXCEPTION; PRAGMA EXCEPTION_INIT(NUMBER_TO_BIG,

为了更容易地解释我的问题,我将粘贴我的全部代码:

drop table tst;

create table tst
(t1 number(2));

set serveroutput on
DECLARE
  TYPE vltp IS TABLE OF NUMBER(3);
  vl vltp := vltp(2,12,33,344,55,66,7,555,4);
  NUMBER_TO_BIG EXCEPTION;
  PRAGMA EXCEPTION_INIT(NUMBER_TO_BIG, -01438);
BEGIN
  FOR i IN vl.FIRST .. vl.LAST LOOP
    INSERT INTO tst VALUES (vl(i));
    SAVEPOINT ONE;
    END LOOP;
EXCEPTION
  WHEN NUMBER_TO_BIG THEN
    ROLLBACK TO SAVEPOINT ONE;
END;
/

select * from tst;
基本上,当我在表中插入344时,我会得到一个异常(数字从\u到\u BIG),我希望它回滚到循环,但跳过该数字

预期产出:

tst
-----
2
12
33
55
66
7
4
实际产量:

no rows selected
它正在回滚所有更改,而不仅仅是一个数字


有什么想法吗?

您应该在循环本身内部处理异常。一旦异常得到处理,它将继续循环

SQL> DECLARE
  TYPE vltp IS TABLE OF NUMBER(3);
  vl vltp := vltp(2,12,33,344,55,66,7,555,4);

  NUMBER_TO_BIG EXCEPTION;
  PRAGMA EXCEPTION_INIT(NUMBER_TO_BIG, -01438);

BEGIN
  FOR i IN vl.FIRST .. vl.LAST LOOP
    BEGIN
        INSERT INTO tst VALUES (vl(i));
    EXCEPTION
        WHEN NUMBER_TO_BIG THEN
        NULL;
    END;

    END LOOP;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

PL/SQL procedure successfully completed.


SQL> SELECT * FROM tst;

        T1
----------
         2
        12
        33
        55
        66
         7
         4

7 rows selected.
你应该试试这个

drop table tst;
--create table
create table tst
(t1 number(2));

--start of code
DECLARE
  TYPE vltp IS TABLE OF NUMBER(3);
  vl vltp := vltp(2, 12, 33, 344, 55, 66, 7, 555, 4);
  NUMBER_TO_BIG EXCEPTION;
  PRAGMA EXCEPTION_INIT(NUMBER_TO_BIG, -01438);
BEGIN
  FOR i IN vl.FIRST .. vl.LAST LOOP
    begin
      INSERT INTO tst VALUES (vl(i));
    exception
      when NUMBER_TO_BIG then
         --log exeption into log table here
        dbms_output.put_line(sqlerrm);
    end;
  END LOOP;
  commit;
exception
  when others then
    --log exeption into log table here
    dbms_output.put_line(sqlerrm);
END;

当其他人…在此示例中时,没有理由包含异常。。默认情况下,无论您使用什么工具,都会获得错误信息。使用SQL进行插入和使用LOG ERRORS子句来处理被拒绝的行将更简单、更高效:因此,据我所知,在我的代码中,当它遇到异常时,它会一直跟踪代码,直到找到如何处理它。在您的中,当它到达异常时,因为它在循环中,它将其视为某种“if”语句。所以它到达一个异常,表示:如果异常什么也不做。还是我认为这一切都错了?是的,你的理解是正确的。由于异常处理在循环本身中,它将跳过异常值并继续循环。
drop table tst;
--create table
create table tst
(t1 number(2));

--start of code
DECLARE
  TYPE vltp IS TABLE OF NUMBER(3);
  vl vltp := vltp(2, 12, 33, 344, 55, 66, 7, 555, 4);
  NUMBER_TO_BIG EXCEPTION;
  PRAGMA EXCEPTION_INIT(NUMBER_TO_BIG, -01438);
BEGIN
  FOR i IN vl.FIRST .. vl.LAST LOOP
    begin
      INSERT INTO tst VALUES (vl(i));
    exception
      when NUMBER_TO_BIG then
         --log exeption into log table here
        dbms_output.put_line(sqlerrm);
    end;
  END LOOP;
  commit;
exception
  when others then
    --log exeption into log table here
    dbms_output.put_line(sqlerrm);
END;