MENCOBA... CATCH (Transact-SQL)
Berlaku untuk:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)Titik akhir analitik SQL di Microsoft FabricWarehouse di Microsoft Fabric
Menerapkan penanganan kesalahan untuk Transact-SQL yang mirip dengan penanganan pengecualian dalam bahasa Microsoft Visual C# dan Microsoft Visual C++. Sekelompok pernyataan Transact-SQL dapat diapit dalam blok TRY. Jika kesalahan terjadi di blok TRY, kontrol biasanya diteruskan ke grup pernyataan lain yang diapit dalam blok CATCH.
Sintaksis
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Catatan
Untuk melihat sintaks Transact-SQL untuk SQL Server 2014 (12.x) dan versi yang lebih lama, lihat Dokumentasi versi sebelumnya.
Argumen
sql_statement
Adalah pernyataan Transact-SQL apa pun.
statement_block
Setiap grup pernyataan Transact-SQL dalam batch atau diapit dalam BEGIN... Blok AKHIR.
Keterangan
COBA... Konstruksi CATCH menangkap semua kesalahan eksekusi yang memiliki tingkat keparahan lebih tinggi dari 10 yang tidak menutup koneksi database.
Blok TRY harus segera diikuti oleh blok CATCH terkait. Menyertakan pernyataan lain antara pernyataan END TRY dan BEGIN CATCH menghasilkan kesalahan sintaksis.
COBA... Konstruksi CATCH tidak dapat menjangkau beberapa batch. COBA... Konstruksi CATCH tidak dapat mencakup beberapa blok pernyataan Transact-SQL. Misalnya, TRY... Konstruksi CATCH tidak dapat mencakup dua BEGIN... Blok AKHIR pernyataan Transact-SQL dan tidak dapat menjangkau IF... Konstruksi LAIN.
Jika tidak ada kesalahan dalam kode yang diapit dalam blok TRY, ketika pernyataan terakhir dalam blok TRY telah selesai berjalan, kontrol meneruskan ke pernyataan segera setelah pernyataan END CATCH terkait.
Jika ada kesalahan dalam kode yang diapit dalam blok TRY, kontrol meneruskan ke pernyataan pertama di blok CATCH terkait. Ketika kode di blok CATCH selesai, kontrol meneruskan ke pernyataan segera setelah pernyataan END CATCH.
Catatan
Jika pernyataan END CATCH adalah pernyataan terakhir dalam prosedur atau pemicu tersimpan, kontrol diteruskan kembali ke pernyataan yang disebut prosedur tersimpan atau menembakkan pemicu.
Kesalahan yang terperangkap oleh blok CATCH tidak dikembalikan ke aplikasi panggilan. Jika ada bagian dari informasi kesalahan yang harus dikembalikan ke aplikasi, kode di blok CATCH harus melakukannya dengan menggunakan mekanisme seperti set hasil SELECT atau pernyataan RAISERROR dan PRINT.
MENCOBA... Konstruksi CATCH dapat disarangkan. Blok TRY atau blok CATCH dapat berisi TRY berlapis... KONSTRUKSI CATCH. Misalnya, blok CATCH dapat berisi TRY yang disematkan... Konstruksi CATCH untuk menangani kesalahan yang ditemui oleh kode CATCH.
Kesalahan yang ditemui dalam blok CATCH diperlakukan seperti kesalahan yang dihasilkan di tempat lain. Jika blok CATCH berisi TRY berlapis... Konstruksi CATCH, kesalahan apa pun dalam blok TRY berlapis akan meneruskan kontrol ke blok CATCH berlapis. Jika tidak ada TRY berlapis... Konstruksi CATCH, kesalahan diteruskan kembali ke pemanggil.
MENCOBA... Konstruksi CATCH menangkap kesalahan yang tidak tertangani dari prosedur tersimpan atau pemicu yang dijalankan oleh kode di blok TRY. Atau, prosedur atau pemicu yang disimpan dapat berisi TRY mereka sendiri... Konstruksi CATCH untuk menangani kesalahan yang dihasilkan oleh kode mereka. Misalnya, ketika blok TRY menjalankan prosedur tersimpan dan kesalahan terjadi dalam prosedur tersimpan, kesalahan dapat ditangani dengan cara berikut:
Jika prosedur tersimpan tidak berisi TRY sendiri... Konstruksi CATCH, kesalahan mengembalikan kontrol ke blok CATCH yang terkait dengan blok TRY yang berisi pernyataan EXECUTE.
Jika prosedur tersimpan berisi TRY... KONSTRUKSI CATCH, kesalahan mentransfer kontrol ke blok CATCH dalam prosedur tersimpan. Ketika kode blok CATCH selesai, kontrol diteruskan kembali ke pernyataan segera setelah pernyataan EXECUTE yang disebut prosedur tersimpan.
Pernyataan GOTO tidak dapat digunakan untuk memasukkan blok TRY atau CATCH. Pernyataan GOTO dapat digunakan untuk melompat ke label di dalam blok TRY atau CATCH yang sama atau untuk meninggalkan blok TRY atau CATCH.
COBA... Konstruksi CATCH tidak dapat digunakan dalam fungsi yang ditentukan pengguna.
Mengambil Informasi Kesalahan
Dalam cakupan blok CATCH, fungsi sistem berikut dapat digunakan untuk mendapatkan informasi tentang kesalahan yang menyebabkan blok CATCH dijalankan:
ERROR_NUMBER() mengembalikan jumlah kesalahan.
ERROR_SEVERITY() mengembalikan tingkat keparahan.
ERROR_STATE() mengembalikan nomor status kesalahan.
ERROR_PROCEDURE() mengembalikan nama prosedur tersimpan atau pemicu tempat kesalahan terjadi.
ERROR_LINE() mengembalikan nomor baris di dalam rutinitas yang menyebabkan kesalahan.
ERROR_MESSAGE() mengembalikan teks lengkap pesan kesalahan. Teks mencakup nilai yang disediakan untuk parameter yang dapat diganti, seperti panjang, nama objek, atau waktu.
Fungsi-fungsi ini mengembalikan NULL jika dipanggil di luar cakupan blok CATCH. Informasi kesalahan dapat diambil dengan menggunakan fungsi-fungsi ini dari mana saja dalam cakupan blok CATCH. Misalnya, skrip berikut menunjukkan prosedur tersimpan yang berisi fungsi penanganan kesalahan. CATCH
Di blok TRY...CATCH
konstruksi, prosedur tersimpan dipanggil dan informasi tentang kesalahan dikembalikan.
-- Verify that the stored procedure does not already exist.
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL
DROP PROCEDURE usp_GetErrorInfo;
GO
-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
GO
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;
END CATCH;
Fungsi ERROR_* juga berfungsi di blok di CATCH
dalam prosedur tersimpan yang dikompilasi secara asli.
Kesalahan Tidak Terpengaruh oleh TRY... KONSTRUKSI CATCH
MENCOBA... Konstruksi CATCH tidak menjebak kondisi berikut:
Peringatan atau pesan informasi yang memiliki tingkat keparahan 10 atau lebih rendah.
Kesalahan yang memiliki tingkat keparahan 20 atau lebih tinggi yang menghentikan pemrosesan tugas Mesin Database SQL Server untuk sesi tersebut. Jika terjadi kesalahan yang memiliki tingkat keparahan 20 atau lebih tinggi dan koneksi database tidak terganggu, TRY... CATCH akan menangani kesalahan.
Perhatian, seperti permintaan yang mengganggu klien atau koneksi klien yang rusak.
Ketika sesi berakhir oleh administrator sistem dengan menggunakan pernyataan KILL.
Jenis kesalahan berikut tidak ditangani oleh blok CATCH ketika terjadi pada tingkat eksekusi yang sama dengan TRY... Konstruksi CATCH:
Kompilasi kesalahan, seperti kesalahan sintaksis, yang mencegah batch berjalan.
Kesalahan yang terjadi selama kompilasi ulang tingkat pernyataan, seperti kesalahan resolusi nama objek yang terjadi setelah kompilasi karena resolusi nama yang ditangguhkan.
Kesalahan resolusi nama objek
Kesalahan ini dikembalikan ke tingkat yang menjalankan batch, prosedur tersimpan, atau pemicu.
Jika terjadi kesalahan selama kompilasi atau kompilasi ulang tingkat pernyataan pada tingkat eksekusi yang lebih rendah (misalnya, saat menjalankan sp_executesql atau prosedur tersimpan yang ditentukan pengguna) di dalam blok TRY, kesalahan terjadi pada tingkat yang lebih rendah daripada TRY... Konstruksi CATCH dan akan ditangani oleh blok CATCH terkait.
Contoh berikut menunjukkan bagaimana kesalahan resolusi nama objek yang SELECT
dihasilkan oleh pernyataan tidak ditangkap oleh TRY...CATCH
konstruksi, tetapi ditangkap oleh CATCH
blok ketika pernyataan yang sama SELECT
dijalankan di dalam prosedur tersimpan.
BEGIN TRY
-- Table does not exist; object name resolution
-- error not caught.
SELECT * FROM NonexistentTable;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
Kesalahan tidak tertangkap dan kontrol melewati TRY...CATCH
konstruksi ke tingkat yang lebih tinggi berikutnya.
Menjalankan pernyataan di SELECT
dalam prosedur tersimpan akan menyebabkan kesalahan terjadi pada tingkat yang lebih rendah dari TRY
blok. Kesalahan akan ditangani oleh TRY...CATCH
konstruksi.
-- Verify that the stored procedure does not exist.
IF OBJECT_ID ( N'usp_ExampleProc', N'P' ) IS NOT NULL
DROP PROCEDURE usp_ExampleProc;
GO
-- Create a stored procedure that will cause an
-- object resolution error.
CREATE PROCEDURE usp_ExampleProc
AS
SELECT * FROM NonexistentTable;
GO
BEGIN TRY
EXECUTE usp_ExampleProc;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
Transaksi dan XACT_STATE tidak dapat diterapkan
Jika kesalahan yang dihasilkan dalam blok TRY menyebabkan status transaksi saat ini tidak valid, transaksi diklasifikasikan sebagai transaksi yang tidak dapat diterapkan. Kesalahan yang biasanya mengakhiri transaksi di luar blok TRY menyebabkan transaksi memasuki status tidak dapat diterapkan ketika kesalahan terjadi di dalam blok TRY. Transaksi yang tidak dapat diterapkan hanya dapat melakukan operasi baca atau TRANSAKSI ROLLBACK. Transaksi tidak dapat menjalankan pernyataan Transact-SQL apa pun yang akan menghasilkan operasi tulis atau COMMIT TRANSACTION. Fungsi XACT_STATE mengembalikan nilai -1 jika transaksi telah diklasifikasikan sebagai transaksi yang tidak dapat diterapkan. Ketika batch selesai, Mesin Database mengembalikan transaksi aktif yang tidak dapat diterapkan. Jika tidak ada pesan kesalahan yang dikirim ketika transaksi memasuki status yang tidak dapat diterapkan, ketika batch selesai, pesan kesalahan akan dikirim ke aplikasi klien. Ini menunjukkan bahwa transaksi yang tidak dapat diterapkan terdeteksi dan digulung balik.
Untuk informasi selengkapnya tentang transaksi yang tidak dapat diterapkan dan fungsi XACT_STATE, lihat XACT_STATE (Transact-SQL).
Contoh
J. Menggunakan TRY... MENANGKAP
Contoh berikut menunjukkan SELECT
pernyataan yang akan menghasilkan kesalahan bagi-demi-nol. Kesalahan menyebabkan eksekusi melompat ke blok terkait CATCH
.
BEGIN TRY
-- Generate a divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO
B. Menggunakan TRY... CATCH dalam transaksi
Contoh berikut menunjukkan cara TRY...CATCH
kerja blok di dalam transaksi. Pernyataan di TRY
dalam blok menghasilkan kesalahan pelanggaran batasan.
BEGIN TRANSACTION;
BEGIN TRY
-- Generate a constraint violation error.
DELETE FROM Production.Product
WHERE ProductID = 980;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
C. Menggunakan TRY... CATCH dengan XACT_STATE
Contoh berikut menunjukkan cara menggunakan TRY...CATCH
konstruksi untuk menangani kesalahan yang terjadi di dalam transaksi. Fungsi menentukan XACT_STATE
apakah transaksi harus dilakukan atau digulung balik. Dalam contoh ini, SET XACT_ABORT
adalah ON
. Ini membuat transaksi tidak dapat diterapkan ketika kesalahan pelanggaran batasan terjadi.
-- Check to see whether this stored procedure exists.
IF OBJECT_ID (N'usp_GetErrorInfo', N'P') IS NOT NULL
DROP PROCEDURE usp_GetErrorInfo;
GO
-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_LINE () AS ErrorLine
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_MESSAGE() AS ErrorMessage;
GO
-- SET XACT_ABORT ON will cause the transaction to be uncommittable
-- when the constraint violation occurs.
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- A FOREIGN KEY constraint exists on this table. This
-- statement will generate a constraint violation error.
DELETE FROM Production.Product
WHERE ProductID = 980;
-- If the DELETE statement succeeds, commit the transaction.
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;
-- Test XACT_STATE:
-- If 1, the transaction is committable.
-- If -1, the transaction is uncommittable and should
-- be rolled back.
-- XACT_STATE = 0 means that there is no transaction and
-- a commit or rollback operation would generate an error.
-- Test whether the transaction is uncommittable.
IF (XACT_STATE()) = -1
BEGIN
PRINT
N'The transaction is in an uncommittable state.' +
'Rolling back transaction.'
ROLLBACK TRANSACTION;
END;
-- Test whether the transaction is committable.
-- You may want to commit a transaction in a catch block if you want to commit changes to statements that ran prior to the error.
IF (XACT_STATE()) = 1
BEGIN
PRINT
N'The transaction is committable.' +
'Committing transaction.'
COMMIT TRANSACTION;
END;
END CATCH;
GO
Lihat Juga
THROW (Transact-SQL)
Tingkat Keparahan Kesalahan Mesin Database
ERROR_LINE (T-SQL)
ERROR_MESSAGE (T-SQL)
ERROR_NUMBER (T-SQL)
ERROR_PROCEDURE (T-SQL)
ERROR_SEVERITY (T-SQL)
ERROR_STATE (T-SQL)
RAISERROR (Transact-SQL)
@@ERROR (T-SQL)
GOTO (T-SQL)
MULAI... END (Transact-SQL)
XACT_STATE (T-SQL)
SET XACT_ABORT (Transact-SQL)
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk