在存储过程中的 PL/SQL 或 SQL Oracle Developer 中引发异常
Raising an Exception in PL/SQL or SQL Oracle Developer within a Stored Procedure
我正在尝试处理 SQLPLUS 中的自定义异常,我有两个存储过程,第二个存储过程调用第一个。
在第一个存储过程中,我有一个检查 table 中行的 data_types 的 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 终止了循环的其余部分的执行,因此它不会获取其他 tables 及其行。
如果有 SQL 向导可以帮助我解决问题,我将不胜感激。我需要知道如何使我的 LOOP 和存储过程在引发异常后继续执行。
如果您希望 FOR 循环在异常发生后继续,请将嵌套块放在 FOR 循环中。
(您也不需要为自定义异常单独声明。)
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;
/
我正在尝试处理 SQLPLUS 中的自定义异常,我有两个存储过程,第二个存储过程调用第一个。
在第一个存储过程中,我有一个检查 table 中行的 data_types 的 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 终止了循环的其余部分的执行,因此它不会获取其他 tables 及其行。
如果有 SQL 向导可以帮助我解决问题,我将不胜感激。我需要知道如何使我的 LOOP 和存储过程在引发异常后继续执行。
如果您希望 FOR 循环在异常发生后继续,请将嵌套块放在 FOR 循环中。
(您也不需要为自定义异常单独声明。)
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;
/