【问题标题】:Raising an Exception in PL/SQL or SQL Oracle Developer within a Stored Procedure在存储过程中的 PL/SQL 或 SQL Oracle Developer 中引发异常
【发布时间】:2021-11-29 07:31:29
【问题描述】:

我试图在 SQLPLUS 中处理一个自定义异常,我有两个存储过程,我有第二个存储过程调用第一个。

在第一个存储过程中,我有一个 CASE 检查表中行的数据类型,如果类型不是 CHAR、VARCHAR2、DATE 或 NUMBER,那么它应该显示 Data_Type 和 RAISE_APPLICATION_ERROR我在调用第一个过程的第二个过程中声明的客户异常。

这是我的第二个存储过程中的代码:

 CASE CurrentRow.Data_Type 
      WHEN 'CHAR' THEN
      wDataType := (CurrentRow.Data_Type || '(' || CurrentRow.CHAR_LENGTH || ')');      
      WHEN 'VARCHAR2' THEN
      wDataType := (CurrentRow.Data_Type || '(' || CurrentRow.CHAR_LENGTH || ')');
      WHEN 'DATE' THEN
      wDataType := (CurrentRow.Data_Type);
      WHEN 'NUMBER' THEN
      wDataType := (CurrentRow.Data_Type || '(' || CurrentRow.Data_Precision || ',' || CurrentRow.Data_Scale || ')');
    ELSE
      wDataType := (CurrentRow.Data_Type);
      RAISE_APPLICATION_ERROR(-20100, '*** Unknown Data Type ' || CurrentRow.Data_Type || ' ***');      
    END CASE;

现在我的第二个存储过程中有一个嵌套块,但无论我将它放在哪里或尝试将它放在周围,只要引发错误?它停止执行我的其余代码,这就是我的问题。我感觉我的嵌套块可能在我的第二个存储过程中没有正确执行......

下面是调用我的第一个存储过程的第二个存储过程的代码:

CREATE OR REPLACE PROCEDURE Get_Tables
/*
* Sept 26th, 2021
* To process each table in the schema, and output table-related lines.
*/
AS 
  CURSOR TablesSelected IS
    SELECT Table_Name
    FROM User_Tables
    ORDER BY Table_Name ASC;
  CurrentRow User_Tables%ROWTYPE;
  dt DATE := sysdate;
  wVersionNumber VARCHAR(4) := 'V3.0';
  wLeftPadTableName VARCHAR(100);
  wLengthOfStatement VARCHAR(100);

BEGIN
  DBMS_OUTPUT.PUT_LINE( '---- Oracle Catalog Extract Utility ' || wVersionNumber || ' ----' );
  DBMS_OUTPUT.PUT_LINE( '----' );
  DBMS_OUTPUT.PUT_LINE( '---- Run on '|| TO_CHAR(dt,'Mon DD,YYYY','NLS_DATE_LANGUAGE=English')||' at '||TO_CHAR(dt,'HH24:MI') );
  DBMS_OUTPUT.PUT_LINE( '----' );
  DBMS_OUTPUT.PUT_LINE( '---- S T A R T I N G  T A B L E  D R O P S' );
  DBMS_OUTPUT.PUT_LINE( '----' );

  FOR CurrentRow IN TablesSelected LOOP
    DBMS_OUTPUT.PUT_LINE( 'DROP TABLE ' || CurrentRow.Table_Name);
  END LOOP;

  DBMS_OUTPUT.PUT_LINE( '----' );
  DBMS_OUTPUT.PUT_LINE( '---- T A B L E  D R O P S  C O M P L E T E D' );
  DBMS_OUTPUT.PUT_LINE( '----' );
  DBMS_OUTPUT.PUT_LINE( '----' );
  DBMS_OUTPUT.PUT_LINE( '---- S T A R T I N G  T A B L E  C R E A T E' );
  DBMS_OUTPUT.PUT_LINE( '----' );

/* 
* Nested block starts
* LOOP gets all the tables in the database and aligns them up. 
*/
    DECLARE
      INVALID_COLUMN_EXCEPTION EXCEPTION;
      PRAGMA EXCEPTION_INIT(INVALID_COLUMN_EXCEPTION, -20100);
    BEGIN

  FOR CurrentRow IN TablesSelected LOOP
    wLengthOfStatement := LENGTH('CREATE TABLE' || CurrentRow.Table_Name || ' ' || '); -- ');
    wLeftPadTableName := LPAD('); -- ', wLengthOfStatement, ' ');
    DBMS_OUTPUT.PUT_LINE( '--   Start extracting table ' || CurrentRow.Table_Name);
    DBMS_OUTPUT.PUT_LINE('CREATE TABLE ' || CurrentRow.Table_Name || '( ');
    Extract_Columns(CurrentRow.Table_Name);
    DBMS_OUTPUT.PUT_LINE(wLeftPadTableName || 'END of table ' || CurrentRow.Table_Name || ' creation');
    DBMS_OUTPUT.PUT_LINE( '--' );
    DBMS_OUTPUT.PUT_LINE( '--' );
  END LOOP;

    EXCEPTION
      WHEN INVALID_COLUMN_EXCEPTION THEN
    DBMS_OUTPUT.PUT_LINE('================================================================================');   
        DBMS_OUTPUT.PUT_LINE('== EXCEPTION ' || SQLCODE || ' Raised - ' || SQLERRM);
        DBMS_OUTPUT.PUT_LINE('== Unable to complete table generation for ' || CurrentRow.Table_Name);
        DBMS_OUTPUT.PUT_LINE('================================================================================');
    END;

/* 
* Nested block ends 
*/

  DBMS_OUTPUT.PUT_LINE( '---- T A B L E  C R E A T E  C O M P L E T E D' );
  DBMS_OUTPUT.PUT_LINE( '----' );
  DBMS_OUTPUT.PUT_LINE( '---- Oracle Catalog Extract Utility ' || wVersionNumber || ' ----' );
  DBMS_OUTPUT.PUT_LINE( '---- Run Completed on '||TO_CHAR(dt,'Mon DD,YYYY','NLS_DATE_LANGUAGE=English')||' at '||TO_CHAR(dt,'HH24:MI') );

END;
/

当我打印出我的报告时...我提出的 ERROR 会终止循环其余部分的执行,因此它不会抓取其他表及其行。

如果有任何 SQL 向导可以帮助我找出我的问题,我将不胜感激。我需要知道我可以做些什么来使我的 LOOP 和存储过程 CONTINUE 继续执行,即使在引发了 EXCEPTION 之后也是如此。

【问题讨论】:

    标签: oracle exception stored-procedures sqlplus


    【解决方案1】:

    如果您希望 FOR 循环在 EXCEPTION 发生后继续,请将嵌套块放在 FOR 循环内。
    (您也不需要为自定义 EXCEPTION 单独声明。)

    CREATE OR REPLACE PROCEDURE Get_Tables
    AS 
      CURSOR TablesSelected IS
        SELECT Table_Name
        FROM User_Tables
        ORDER BY Table_Name ASC;
      CurrentRow User_Tables%ROWTYPE;
      dt DATE := sysdate;
      wVersionNumber VARCHAR(4) := 'V3.0';
      wLeftPadTableName VARCHAR(100);
      wLengthOfStatement VARCHAR(100);
      INVALID_COLUMN_EXCEPTION EXCEPTION;
      PRAGMA EXCEPTION_INIT(INVALID_COLUMN_EXCEPTION, -20100);
    BEGIN
      DBMS_OUTPUT.PUT_LINE( '---- Oracle Catalog Extract Utility ' || wVersionNumber || ' ----' );
      DBMS_OUTPUT.PUT_LINE( '----' );
      DBMS_OUTPUT.PUT_LINE( '---- Run on '|| TO_CHAR(dt,'Mon DD,YYYY','NLS_DATE_LANGUAGE=English')||' at '||TO_CHAR(dt,'HH24:MI') );
      DBMS_OUTPUT.PUT_LINE( '----' );
      DBMS_OUTPUT.PUT_LINE( '---- S T A R T I N G  T A B L E  D R O P S' );
      DBMS_OUTPUT.PUT_LINE( '----' );
    
      FOR CurrentRow IN TablesSelected LOOP
        DBMS_OUTPUT.PUT_LINE( 'DROP TABLE ' || CurrentRow.Table_Name);
      END LOOP;
    
      DBMS_OUTPUT.PUT_LINE( '----' );
      DBMS_OUTPUT.PUT_LINE( '---- T A B L E  D R O P S  C O M P L E T E D' );
      DBMS_OUTPUT.PUT_LINE( '----' );
      DBMS_OUTPUT.PUT_LINE( '----' );
      DBMS_OUTPUT.PUT_LINE( '---- S T A R T I N G  T A B L E  C R E A T E' );
      DBMS_OUTPUT.PUT_LINE( '----' );
    
      FOR CurrentRow IN TablesSelected LOOP
        wLengthOfStatement := LENGTH('CREATE TABLE' || CurrentRow.Table_Name || ' ' || '); -- ');
        wLeftPadTableName := LPAD('); -- ', wLengthOfStatement, ' ');
        DBMS_OUTPUT.PUT_LINE( '--   Start extracting table ' || CurrentRow.Table_Name);
        DBMS_OUTPUT.PUT_LINE('CREATE TABLE ' || CurrentRow.Table_Name || '( ');
      /* 
       * Nested block starts
       */
        BEGIN
          Extract_Columns(CurrentRow.Table_Name);
        EXCEPTION
          WHEN INVALID_COLUMN_EXCEPTION THEN
            DBMS_OUTPUT.PUT_LINE('================================================================================');
            DBMS_OUTPUT.PUT_LINE('== EXCEPTION ' || SQLCODE || ' Raised - ' || SQLERRM);
            DBMS_OUTPUT.PUT_LINE('== Unable to complete table generation for ' || CurrentRow.Table_Name);
            DBMS_OUTPUT.PUT_LINE('================================================================================');
        END;
      /*
       * Nested block ends 
       */
        DBMS_OUTPUT.PUT_LINE(wLeftPadTableName || 'END of table ' || CurrentRow.Table_Name || ' creation');
        DBMS_OUTPUT.PUT_LINE( '--' );
        DBMS_OUTPUT.PUT_LINE( '--' );
      END LOOP;
    
      DBMS_OUTPUT.PUT_LINE( '---- T A B L E  C R E A T E  C O M P L E T E D' );
      DBMS_OUTPUT.PUT_LINE( '----' );
      DBMS_OUTPUT.PUT_LINE( '---- Oracle Catalog Extract Utility ' || wVersionNumber || ' ----' );
      DBMS_OUTPUT.PUT_LINE( '---- Run Completed on '||TO_CHAR(dt,'Mon DD,YYYY','NLS_DATE_LANGUAGE=English')||' at '||TO_CHAR(dt,'HH24:MI') );
    END;
    /
    

    【讨论】:

      猜你喜欢
      • 2012-05-16
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 2021-09-11
      • 2010-09-18
      • 2017-12-21
      相关资源
      最近更新 更多