Kesalahan perangkap - Amazon Redshift

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Kesalahan perangkap

Ketika kueri atau perintah dalam prosedur tersimpan menyebabkan kesalahan, kueri berikutnya tidak berjalan dan transaksi dibatalkan. Tetapi Anda dapat menangani kesalahan menggunakan blok EXCEPTION.

catatan

Perilaku default adalah bahwa kesalahan akan menyebabkan kueri berikutnya tidak berjalan, bahkan ketika tidak ada kondisi penghasil kesalahan tambahan dalam prosedur yang disimpan.

[ <<label>> ] [ DECLARE declarations ] BEGIN statements EXCEPTION WHEN OTHERS THEN statements END;

Ketika pengecualian terjadi, dan Anda menambahkan blok penanganan pengecualian, Anda dapat menulis pernyataan RAISE dan sebagian besar pernyataan PL/PGSQL lainnya. Misalnya, Anda dapat memunculkan pengecualian dengan pesan khusus atau menyisipkan catatan ke dalam tabel logging.

Saat memasuki blok penanganan pengecualian, transaksi saat ini dibatalkan dan transaksi baru dibuat untuk menjalankan pernyataan di blok. Jika pernyataan di blok berjalan tanpa kesalahan, transaksi dilakukan dan pengecualian dilemparkan kembali. Terakhir, prosedur yang disimpan keluar.

Satu-satunya kondisi yang didukung dalam blok pengecualian adalah OTHERS, yang cocok dengan setiap jenis kesalahan kecuali pembatalan kueri. Juga, jika terjadi kesalahan di blok penanganan pengecualian, itu dapat ditangkap oleh blok penanganan pengecualian luar.

Ketika kesalahan terjadi di dalam prosedur NONATOMIC, kesalahan tidak dilemparkan kembali jika ditangani oleh blok pengecualian. Lihat pernyataan PL/PGSQL RAISE untuk melempar pengecualian yang ditangkap oleh blok penanganan pengecualian. Pernyataan ini hanya valid di blok penanganan pengecualian. Untuk informasi selengkapnya, lihat MENAIKKAN.

Mengontrol apa yang terjadi setelah kesalahan dalam prosedur tersimpan, dengan pengendali CONTINUE

CONTINUEHandler adalah jenis handler pengecualian yang mengontrol aliran eksekusi dalam prosedur tersimpan NONATOMIC. Dengan menggunakannya, Anda dapat menangkap dan menangani pengecualian tanpa mengakhiri blok pernyataan yang ada. Biasanya, ketika kesalahan terjadi dalam prosedur yang disimpan, aliran terganggu dan kesalahan dikembalikan ke pemanggil. Namun, dalam beberapa kasus penggunaan, kondisi kesalahan tidak cukup parah untuk menjamin gangguan aliran. Anda mungkin ingin menangani kesalahan dengan anggun, menggunakan logika penanganan kesalahan yang Anda pilih dalam transaksi terpisah, dan kemudian melanjutkan menjalankan pernyataan yang mengikuti kesalahan. Berikut ini menunjukkan sintaks.

[ DECLARE declarations ] BEGIN statements EXCEPTION [ CONTINUE_HANDLER | EXIT_HANDLER ] WHEN OTHERS THEN handler_statements END;

Ada beberapa tabel sistem yang tersedia untuk membantu Anda mengumpulkan informasi tentang berbagai jenis kesalahan. Lihat informasi selengkapnya di STL_LOAD_ERRORS, STL_ERROR, dan SYS_STREAM_SCAN_ERRORS. Ada juga tabel sistem tambahan yang dapat Anda gunakan untuk memecahkan masalah kesalahan. Informasi lebih lanjut tentang ini dapat ditemukan diTabel sistem dan tampilan referensi.

Contoh

Contoh berikut menunjukkan cara menulis pernyataan di blok penanganan pengecualian. Prosedur tersimpan menggunakan perilaku manajemen transaksi default.

CREATE TABLE employee (firstname varchar, lastname varchar); INSERT INTO employee VALUES ('Tomas','Smith'); CREATE TABLE employee_error_log (message varchar); CREATE OR REPLACE PROCEDURE update_employee_sp() AS $$ BEGIN UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith'; EXECUTE 'select invalid'; EXCEPTION WHEN OTHERS THEN RAISE INFO 'An exception occurred.'; INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM); END; $$ LANGUAGE plpgsql; CALL update_employee_sp(); INFO: An exception occurred. ERROR: column "invalid" does not exist CONTEXT: SQL statement "select invalid" PL/pgSQL function "update_employee_sp" line 3 at execute statement

Dalam contoh ini, jika kita memanggilupdate_employee_sp, pesan informasi Pengecualian terjadi. dinaikkan dan pesan kesalahan dimasukkan ke dalam employee_error_log log tabel logging. Pengecualian asli dilemparkan lagi sebelum prosedur yang disimpan keluar. Kueri berikut menunjukkan catatan yang dihasilkan dari menjalankan contoh.

SELECT * from employee; firstname | lastname -----------+---------- Tomas | Smith SELECT * from employee_error_log; message ------------------------------------------------ Error message: column "invalid" does not exist

Untuk informasi selengkapnya tentang RAISE, termasuk bantuan pemformatan dan daftar level tambahan, lihatPernyataan PL/PGSQL yang didukung.

Contoh berikut menunjukkan cara menulis pernyataan di blok penanganan pengecualian. Prosedur tersimpan menggunakan perilaku manajemen transaksi NONATOMIC. Dalam contoh ini, tidak ada kesalahan yang dilemparkan kembali ke pemanggil setelah panggilan prosedur selesai. Pernyataan UPDATE tidak dibatalkan karena kesalahan dalam pernyataan berikutnya. Pesan informasi dimunculkan dan pesan kesalahan dimasukkan dalam tabel logging.

CREATE TABLE employee (firstname varchar, lastname varchar); INSERT INTO employee VALUES ('Tomas','Smith'); CREATE TABLE employee_error_log (message varchar); -- Create the SP in NONATOMIC mode CREATE OR REPLACE PROCEDURE update_employee_sp_2() NONATOMIC AS $$ BEGIN UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith'; EXECUTE 'select invalid'; EXCEPTION WHEN OTHERS THEN RAISE INFO 'An exception occurred.'; INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM); END; $$ LANGUAGE plpgsql; CALL update_employee_sp_2(); INFO: An exception occurred. CALL SELECT * from employee; firstname | lastname -----------+---------- Adam | Smith (1 row) SELECT * from employee_error_log; message ------------------------------------------------ Error message: column "invalid" does not exist (1 row)

Contoh ini menunjukkan cara membuat prosedur dengan dua sub blok. Ketika prosedur tersimpan dipanggil, kesalahan dari sub blok pertama ditangani oleh blok penanganan pengecualian. Setelah sub blok pertama selesai, prosedur terus mengeksekusi sub blok kedua. Anda dapat melihat dari hasil bahwa tidak ada kesalahan yang dilemparkan ketika panggilan prosedur selesai. Operasi UPDATE dan INSERT pada karyawan meja berkomitmen. Pesan kesalahan dari kedua blok pengecualian disisipkan dalam tabel logging.

CREATE TABLE employee (firstname varchar, lastname varchar); INSERT INTO employee VALUES ('Tomas','Smith'); CREATE TABLE employee_error_log (message varchar); CREATE OR REPLACE PROCEDURE update_employee_sp_3() NONATOMIC AS $$ BEGIN BEGIN UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith'; EXECUTE 'select invalid1'; EXCEPTION WHEN OTHERS THEN RAISE INFO 'An exception occurred in the first block.'; INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM); END; BEGIN INSERT INTO employee VALUES ('Edie','Robertson'); EXECUTE 'select invalid2'; EXCEPTION WHEN OTHERS THEN RAISE INFO 'An exception occurred in the second block.'; INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM); END; END; $$ LANGUAGE plpgsql; CALL update_employee_sp_3(); INFO: An exception occurred in the first block. INFO: An exception occurred in the second block. CALL SELECT * from employee; firstname | lastname -----------+----------- Adam | Smith Edie | Robertson (2 rows) SELECT * from employee_error_log; message ------------------------------------------------- Error message: column "invalid1" does not exist Error message: column "invalid2" does not exist (2 rows)

Contoh berikut menunjukkan cara menggunakan handler pengecualian CONTINUE. Sampel ini membuat dua tabel dan menggunakannya dalam prosedur tersimpan. Handler CONTINUE mengontrol aliran eksekusi dalam prosedur tersimpan dengan perilaku manajemen transaksi NONATOMIC.

CREATE TABLE tbl_1 (a int); CREATE TABLE tbl_error_logging(info varchar, err_state varchar, err_msg varchar); CREATE OR REPLACE PROCEDURE sp_exc_handling_1() NONATOMIC AS $$ BEGIN INSERT INTO tbl_1 VALUES (1); -- Expect an error for the insert statement following, because of the invalid value INSERT INTO tbl_1 VALUES ("val"); INSERT INTO tbl_1 VALUES (2); EXCEPTION CONTINUE_HANDLER WHEN OTHERS THEN INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM); END; $$ LANGUAGE plpgsql;

Panggil prosedur yang disimpan:

CALL sp_exc_handling_1();

Aliran berlangsung seperti ini:

  1. Terjadi kesalahan karena upaya dilakukan untuk menyisipkan tipe data yang tidak kompatibel dalam kolom. Kontrol lolos ke blok EXCEPTION. Ketika blok penanganan pengecualian dimasukkan, transaksi saat ini dibatalkan dan transaksi implisit baru dibuat untuk menjalankan pernyataan di dalamnya.

  2. Jika pernyataan di CONTINUE_HANDLER berjalan tanpa kesalahan, kontrol akan diteruskan ke pernyataan segera setelah pernyataan yang menyebabkan pengecualian. (Jika pernyataan di CONTINUE_HANDLER memunculkan pengecualian baru, Anda dapat menanganinya dengan penangan pengecualian di dalam blok EXCEPTION.)

Setelah Anda memanggil prosedur tersimpan sampel, tabel berisi catatan berikut:

  • Jika Anda menjalankanSELECT * FROM tbl_1;, ia mengembalikan dua catatan. Ini berisi nilai-nilai 1 dan2.

  • Jika Anda menjalankanSELECT * FROM tbl_error_logging;, ia mengembalikan satu catatan dengan nilai-nilai ini: Error yang ditemui, 42703, dan kolom “val” tidak ada di tbl_1.

Contoh penanganan kesalahan tambahan berikut menggunakan handler EXIT dan handler CONTINUE. Ini menciptakan dua tabel: tabel data dan tabel logging. Ini juga menciptakan prosedur tersimpan yang menunjukkan penanganan kesalahan:

CREATE TABLE tbl_1 (a int); CREATE TABLE tbl_error_logging(info varchar, err_state varchar, err_msg varchar); CREATE OR REPLACE PROCEDURE sp_exc_handling_2() NONATOMIC AS $$ BEGIN INSERT INTO tbl_1 VALUES (1); BEGIN INSERT INTO tbl_1 VALUES (100); -- Expect an error for the insert statement following, because of the invalid value INSERT INTO tbl_1 VALUES ("val"); INSERT INTO tbl_1 VALUES (101); EXCEPTION EXIT_HANDLER WHEN OTHERS THEN INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM); END; INSERT INTO tbl_1 VALUES (2); -- Expect an error for the insert statement following, because of the invalid value INSERT INTO tbl_1 VALUES ("val"); INSERT INTO tbl_1 VALUES (3); EXCEPTION CONTINUE_HANDLER WHEN OTHERS THEN INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM); END; $$ LANGUAGE plpgsql;

Setelah Anda membuat prosedur yang disimpan, sebut saja dengan yang berikut:

CALL sp_exc_handling_2();

Ketika kesalahan terjadi di blok pengecualian bagian dalam, yang dikurung oleh set bagian dalam BEGIN dan END, itu ditangani oleh pengendali EXIT. Setiap kesalahan yang terjadi di blok luar ditangani oleh handler CONTINUE.

Setelah Anda memanggil prosedur tersimpan sampel, tabel berisi catatan berikut:

  • Jika Anda menjalankanSELECT * FROM tbl_1;, ia mengembalikan empat catatan, dengan nilai 1, 2, 3, dan 100.

  • Jika Anda menjalankanSELECT * FROM tbl_error_logging;, ia mengembalikan dua catatan. Mereka memiliki nilai-nilai ini: Ditemui kesalahan, 42703, dan kolom “val” tidak ada di tbl_1.

Jika tabel tbl_error_logging tidak ada, itu menimbulkan pengecualian.

Contoh berikut menunjukkan cara menggunakan handler pengecualian CONTINUE dengan loop FOR. Sampel ini membuat tiga tabel dan menggunakannya dalam loop FOR dalam prosedur tersimpan. Loop FOR adalah varian set hasil, artinya iterasi atas hasil kueri:

CREATE TABLE tbl_1 (a int); INSERT INTO tbl_1 VALUES (1), (2), (3); CREATE TABLE tbl_2 (a int); CREATE TABLE tbl_error_logging(info varchar, err_state varchar, err_msg varchar); CREATE OR REPLACE PROCEDURE sp_exc_handling_loop() NONATOMIC AS $$ DECLARE rec RECORD; BEGIN FOR rec IN SELECT a FROM tbl_1 LOOP IF rec.a = 2 THEN -- Expect an error for the insert statement following, because of the invalid value INSERT INTO tbl_2 VALUES("val"); ELSE INSERT INTO tbl_2 VALUES (rec.a); END IF; END LOOP; EXCEPTION CONTINUE_HANDLER WHEN OTHERS THEN INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM); END; $$ LANGUAGE plpgsql;

Panggil prosedur yang disimpan:

CALL sp_exc_handling_loop();

Setelah Anda memanggil prosedur tersimpan sampel, tabel berisi catatan berikut:

  • Jika Anda menjalankanSELECT * FROM tbl_2;, ia mengembalikan dua catatan. Ini berisi nilai 1 dan 3.

  • Jika Anda menjalankanSELECT * FROM tbl_error_logging;, ia mengembalikan satu catatan dengan nilai-nilai ini: Error yang ditemui, 42703, dan kolom “val” tidak ada di tbl_2.

Catatan penggunaan mengenai handler CONTINUE:

  • Kata kunci CONTINUE_HANDLER dan EXIT_HANDLER hanya dapat digunakan dalam prosedur tersimpan NONATOMIC.

  • Kata kunci CONTINUE_HANDLER dan EXIT_HANDLER bersifat opsional. EXIT_HANDLER adalah default.