PL/SQL memfasilitasi pemrogram untuk menangkap kondisi seperti itu menggunakan blok pengecualian dalam program dan tindakan yang tepat diambil terhadap kondisi kesalahan tersebut
Ada dua jenis pengecualian
- Pengecualian yang ditentukan sistem
- Pengecualian yang Ditentukan Pengguna
Penanganan Pengecualian PL/SQL
Sintaks untuk penanganan pengecualian
Berikut ini adalah sintaks umum untuk penanganan pengecualian
Contoh penanganan pengecualian
Mari kita ambil contoh sederhana untuk mendemonstrasikan konsep exception handling. Di sini kita menggunakan tabel PELANGGAN yang sudah dibuat
PILIH* DARI PELANGGAN;
IDNAMEAGEADDRESSSALARY1Ramesh23Allahabad200002Suresh22Kanpur220003Mahesh24Ghaziabad240004Chandan25Noida260005Alex21Paris280006Sunita20Delhi30000Setelah eksekusi kode di atas di SQL Prompt, menghasilkan hasil sebagai berikut
No such customer! PL/SQL procedure successfully completed.
Program di atas harus menampilkan nama dan alamat pelanggan sebagai hasil yang ID-nya diberikan. Tetapi tidak ada pelanggan dengan nilai ID 8 di database kami, sehingga program memunculkan pengecualian run-time NO_DATA_FOUND, yang ditangkap di blok EXCEPTION
Catatan. Anda mendapatkan hasil "No such customer" karena customer_id yang digunakan pada contoh di atas adalah 8 dan tidak ada pelanggan yang memiliki nilai id 8 pada tabel tersebut
Jika Anda menggunakan id yang ditentukan dalam tabel di atas (mis. e. 1 sampai 6), Anda akan mendapatkan hasil tertentu. Untuk contoh demo. di sini, kita menggunakan id 5
Setelah mengeksekusi kode di atas pada prompt SQL, Anda akan mendapatkan hasil sebagai berikut
Name: alex Address: paris PL/SQL procedure successfully completed. _
Meningkatkan Pengecualian
Dalam kasus kesalahan basis data internal, pengecualian dimunculkan oleh server basis data secara otomatis. Tapi itu juga bisa dimunculkan secara eksplisit oleh programmer dengan menggunakan perintah RAISE
Sintaks untuk memunculkan pengecualian
Pengecualian yang Ditentukan Pengguna PL/SQL
PL/SQL memfasilitasi penggunanya untuk menentukan pengecualian mereka sendiri sesuai dengan kebutuhan program. Pengecualian yang ditentukan pengguna dapat dimunculkan secara eksplisit, menggunakan pernyataan RAISE atau prosedur DBMS_STANDARD. RAISE_APPLICATION_ERROR
Sintaks untuk pengecualian yang ditentukan pengguna
Pengecualian yang Ditentukan Sebelumnya PL/SQL
Ada banyak pengecualian yang telah ditentukan sebelumnya dalam PL/SQL yang dijalankan ketika ada aturan basis data yang dilanggar oleh program
Sebagai contoh. NO_DATA_FOUND adalah pengecualian yang ditentukan sebelumnya yang dimunculkan ketika pernyataan SELECT INTO tidak mengembalikan baris
Saat JDBC menemukan kesalahan selama interaksi dengan sumber data, JDBC melempar instance SQLException sebagai kebalikan dari Exception. (Sumber data dalam konteks ini mewakili database tempat objek Connection terhubung. ) Contoh SQLException berisi informasi berikut yang dapat membantu Anda menentukan penyebab kesalahan
Deskripsi kesalahan. Ambil objek String yang berisi deskripsi ini dengan memanggil metode SQLException.getMessage
Kode SQLState. Kode-kode ini dan artinya masing-masing telah distandarisasi oleh ISO/ANSI dan Open Group (X/Open), meskipun beberapa kode telah disediakan untuk vendor database untuk ditentukan sendiri. Objek String_ ini terdiri dari lima karakter alfanumerik. Ambil kode ini dengan memanggil metode SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist. 1
Kode kesalahan. Ini adalah nilai integer yang mengidentifikasi kesalahan yang menyebabkan instance SQLException dilempar. Nilai dan maknanya spesifik untuk implementasi dan mungkin merupakan kode kesalahan aktual yang dikembalikan oleh sumber data yang mendasarinya. Ambil kesalahan dengan memanggil metode SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist. 3
Penyebab. Instance SQLException mungkin memiliki hubungan sebab-akibat, yang terdiri dari satu atau lebih SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist. 5 objek yang menyebabkan instance SQLException dilempar. Untuk menavigasi rantai penyebab ini, panggil metode SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist. 7 secara rekursif hingga nilai SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist. 8 dikembalikan
Referensi ke pengecualian berantai apa pun. Jika terjadi lebih dari satu kesalahan, pengecualian dirujuk melalui rantai ini. Dapatkan kembali pengecualian ini dengan memanggil metode SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist. 9 pada pengecualian yang dilemparkan
Metode berikut, public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 0, menampilkan SQLState, kode kesalahan, deskripsi kesalahan, dan penyebab (jika ada) yang terkandung dalam SQLException serta pengecualian lain yang dirantai padanya
public static void printSQLException(SQLException ex) { for (Throwable e : ex) { if (e instanceof SQLException) { if (ignoreSQLException( ((SQLException)e). getSQLState()) == false) { e.printStackTrace(System.err); System.err.println("SQLState: " + ((SQLException)e).getSQLState()); System.err.println("Error Code: " + ((SQLException)e).getErrorCode()); System.err.println("Message: " + e.getMessage()); Throwable t = ex.getCause(); while(t != null) { System.out.println("Cause: " + t); t = t.getCause(); } } } } } _
Misalnya, jika Anda memanggil metode public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } _2 dengan Java DB sebagai DBMS Anda, tabel public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 3 tidak ada, dan Anda menghapus panggilan ke public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 4, hasilnya akan seperti berikut
SQLState: 42Y55 Error Code: 30000 Message: 'DROP TABLE' cannot be performed on 'TESTDB.COFFEES' because it does not exist.
Alih-alih mencetak SQLException informasi, Anda dapat terlebih dahulu mengambil public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 6 kemudian memproses SQLException sesuai. Misalnya, metode public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 4 mengembalikan public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 9 jika public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 6 sama dengan kode public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 1 (dan Anda menggunakan Java DB sebagai DBMS Anda), yang menyebabkan public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } 0 mengabaikan SQLException
public static boolean ignoreSQLException(String sqlState) { if (sqlState == null) { System.out.println("The SQL state is not defined!"); return false; } // X0Y32: Jar file already exists in schema if (sqlState.equalsIgnoreCase("X0Y32")) return true; // 42Y55: Table already exists in schema if (sqlState.equalsIgnoreCase("42Y55")) return true; return false; } _
public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } _4 objek adalah subkelas dari SQLException yang berhubungan dengan peringatan akses database. Peringatan tidak menghentikan eksekusi aplikasi, seperti halnya pengecualian; . Misalnya, peringatan mungkin memberi tahu Anda bahwa hak istimewa yang Anda coba cabut tidak dicabut. Atau peringatan mungkin memberi tahu Anda bahwa terjadi kesalahan selama pemutusan yang diminta
Peringatan dapat dilaporkan pada objek Connection, objek public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 7 (termasuk objek public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 8 dan public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 9), atau objek SQLException0. Masing-masing kelas ini memiliki metode SQLException_1, yang harus Anda panggil untuk melihat peringatan pertama yang dilaporkan pada objek pemanggil. Jika SQLException_1 mengembalikan peringatan, Anda dapat memanggil metode public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 4 SQLException4 untuk mendapatkan peringatan tambahan. Menjalankan pernyataan secara otomatis menghapus peringatan dari pernyataan sebelumnya, sehingga tidak menumpuk. Ini berarti, bagaimanapun, jika Anda ingin mengambil peringatan yang dilaporkan pada sebuah pernyataan, Anda harus melakukannya sebelum Anda mengeksekusi pernyataan lain
Metode berikut dari SQLException_5 mengilustrasikan cara mendapatkan informasi lengkap tentang peringatan apa pun yang dilaporkan pada objek public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 7 atau SQLException0
public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } }
Peringatan paling umum adalah peringatan SQLException_8, subkelas dari public static void getWarningsFromResultSet(ResultSet rs) throws SQLException { JDBCTutorialUtilities.printWarnings(rs.getWarnings()); } public static void getWarningsFromStatement(Statement stmt) throws SQLException { JDBCTutorialUtilities.printWarnings(stmt.getWarnings()); } public static void printWarnings(SQLWarning warning) throws SQLException { if (warning != null) { System.out.println("\n---Warning---\n"); while (warning != null) { System.out.println("Message: " + warning.getMessage()); System.out.println("SQLState: " + warning.getSQLState()); System.out.print("Vendor error code: "); System.out.println(warning.getErrorCode()); System.out.println(""); warning = warning.getNextWarning(); } } 4. Semua objek SQLException_8 memiliki SQLState Exception1, menunjukkan bahwa ada masalah dengan membaca atau menulis data. SQLException8 metode membiarkan Anda mengetahui di mana kolom atau data parameter dipotong, apakah pemotongan itu pada operasi baca atau tulis, berapa banyak byte yang seharusnya ditransfer, dan berapa banyak byte yang benar-benar ditransfer
Driver JDBC Anda mungkin melempar subkelas SQLException yang sesuai dengan SQLState umum atau status kesalahan umum yang tidak terkait dengan nilai kelas SQLState tertentu. Ini memungkinkan Anda untuk menulis kode penanganan kesalahan yang lebih portabel. Pengecualian ini adalah subkelas dari salah satu kelas berikut
- Exception4
- Exception5
- Exception6
Lihat Javadoc terbaru dari paket Exception7 atau dokumentasi driver JDBC Anda untuk informasi lebih lanjut tentang subkelas ini