Oracle 使用FOR循环和EXECUTE IMMEDIATE处理异常

Oracle 使用FOR循环和EXECUTE IMMEDIATE处理异常,oracle,plsql,Oracle,Plsql,我的任务是打印表的总列数。然后,对于特定ID,只打印那些具有值的列的名称(如果该特定ID的列包含null,则跳过该列)。我在FOR循环中的代码中使用了executeimmediate。如果executeimmediate在列中找不到任何数据,则它不会抛出我可以处理的\u data\u异常,但在该异常之后我无法继续循环 DECLARE COL_TOTAL_NUM NUMBER; COL_NAME VARCHAR2(500); COL_VAL VARCHAR2(500); B

我的任务是打印表的总列数。然后,对于特定ID,只打印那些具有值的列的名称(如果该特定ID的列包含null,则跳过该列)。我在FOR循环中的代码中使用了
executeimmediate
。如果
executeimmediate
在列中找不到任何数据,则它不会抛出我可以处理的\u data\u异常,但在该异常之后我无法继续循环

DECLARE
    COL_TOTAL_NUM NUMBER;
    COL_NAME VARCHAR2(500);
    COL_VAL VARCHAR2(500);
BEGIN
    SELECT COUNT(*) INTO COL_TOTAL_NUM FROM user_tab_cols WHERE TABLE_NAME='PAY_SLIP_FEB_16';
    DBMS_OUTPUT.PUT_LINE('TOTAL COLUMN NUMBER = '||COL_TOTAL_NUM);
    FOR A IN 1..COL_TOTAL_NUM LOOP
      SAVEPOINT S1;
      SELECT COLUMN_NAME INTO COL_NAME FROM user_tab_cols WHERE TABLE_NAME='PAY_SLIP_FEB_16'
                                                  AND COLUMN_ID=A;
      EXECUTE IMMEDIATE 'SELECT '||COL_NAME||' FROM PAY_SLIP_FEB_16 WHERE EMP_ID=''FMINF83057'' AND '||COL_NAME||' IS NOT NULL' INTO COL_NAME;
      DBMS_OUTPUT.PUT_LINE(COL_NAME||' -> '||COL_VAL);
    END LOOP;
    EXCEPTION
      WHEN no_data_found THEN
        DBMS_OUTPUT.PUT_LINE('ERROR');
        ROLLBACK TO SAVEPOINT S1;
END;  
我的输出是:

TOTAL COLUMN NUMBER = 117
EMP_ID -> FMINF83057
MONTH -> 2
YEAR -> 2016
NAME ->   Mr.Md.Mohiduzzaman
DESIGNATION -> Professor
DEPARTMENT -> Institute of Nutrition and Food Sciences
GRADE -> 2
BASIC_PAY -> 73720
HOUSE_RENT_ALLOWANCE -> 19750
MEDICAL_ALLOWANCE -> 700
ERROR  
for循环在此停止。发生错误后,我如何继续执行该操作?

遇到错误时,只需使用语句即可。它从Oracle 11g开始提供。但是你需要在循环中这样做。我将您的异常部分移动到循环中,并将其封闭在一个块中:

DECLARE
    COL_TOTAL_NUM NUMBER;
    COL_NAME VARCHAR2(500);
    COL_VAL VARCHAR2(500);
BEGIN
    SELECT COUNT(*) INTO COL_TOTAL_NUM FROM user_tab_cols WHERE TABLE_NAME='PAY_SLIP_FEB_16';
    DBMS_OUTPUT.PUT_LINE('TOTAL COLUMN NUMBER = '||COL_TOTAL_NUM);
    FOR A IN 1..COL_TOTAL_NUM LOOP
    BEGIN
      SAVEPOINT S1;
      SELECT COLUMN_NAME INTO COL_NAME FROM user_tab_cols WHERE TABLE_NAME='PAY_SLIP_FEB_16'
                                              AND COLUMN_ID=A;
      EXECUTE IMMEDIATE 'SELECT '||COL_NAME||' FROM PAY_SLIP_FEB_16 WHERE EMP_ID=''FMINF83057'' AND '||COL_NAME||' IS NOT NULL' INTO COL_NAME;
      DBMS_OUTPUT.PUT_LINE(COL_NAME||' -> '||COL_VAL);
    EXCEPTION
      WHEN no_data_found THEN
        DBMS_OUTPUT.PUT_LINE('ERROR');
        CONTINUE;                         --move to the next iteration of the loop
    END;
    END LOOP;
END; 

该语句告诉编译器跳过循环的当前迭代并跳到下一个迭代。它对于日志记录特别有用。

所以您想打印
错误
,然后让循环继续?如果是这种情况,您可以这样做,但是循环将从一开始就开始,因为您有
ROLLBACK
命令。我不需要打印错误。我打印了它以确保我能处理异常。我只需要跳过它并继续循环。我不能在for循环中使用异常,因为我没有将它包含在块中,但是在包含循环之后,现在我可以使用它了,非常感谢。