COBA... CATCH (Transact-SQL)
Berlaku untuk: Titik akhir analitik SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Platform System (PDW) SQL di Microsoft Fabric Warehouse di Microsoft Fabric
Menerapkan penanganan kesalahan untuk Transact-SQL yang mirip dengan penanganan pengecualian dalam bahasa C# dan Visual C++. Sekelompok pernyataan Transact-SQL dapat diapit dalam TRY
blok. Jika terjadi kesalahan di blok, kontrol biasanya diteruskan TRY
ke grup pernyataan lain yang diapit dalam CATCH
blok.
Sintaks
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Argumen
sql_statement
Setiap pernyataan T-SQL.
statement_block
Setiap grup pernyataan Transact-SQL dalam batch atau diapit dalam BEGIN...END
blok.
Keterangan
Konstruksi TRY...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 terkait CATCH
. Menyertakan pernyataan lain antara END TRY
pernyataan dan BEGIN CATCH
menghasilkan kesalahan sintaks.
Konstruksi TRY...CATCH
tidak dapat mencakup beberapa batch. Konstruksi TRY...CATCH
tidak dapat mencakup beberapa blok pernyataan Transact-SQL. Misalnya, TRY...CATCH
konstruksi tidak dapat mencakup dua BEGIN...END
blok pernyataan Transact-SQL, dan tidak dapat menjangkau IF...ELSE
konstruksi.
Jika tidak ada kesalahan dalam kode yang diapit dalam TRY
blok, ketika pernyataan terakhir dalam TRY
blok selesai, kontrol meneruskan ke pernyataan segera setelah pernyataan terkait END CATCH
.
Jika ada kesalahan dalam kode yang diapit dalam TRY
blok, kontrol akan meneruskan ke pernyataan pertama di blok terkait CATCH
. Ketika kode di CATCH
blok selesai, kontrol meneruskan ke pernyataan segera setelah END CATCH
pernyataan.
Catatan
END CATCH
Jika pernyataan adalah pernyataan terakhir dalam prosedur atau pemicu yang disimpan, kontrol diteruskan kembali ke pernyataan yang disebut prosedur tersimpan atau menembakkan pemicu.
Kesalahan yang CATCH
terperangkap oleh blok tidak dikembalikan ke aplikasi panggilan. Jika ada bagian dari informasi kesalahan yang harus dikembalikan ke aplikasi, kode dalam CATCH
blok harus melakukannya dengan menggunakan mekanisme seperti SELECT
tataan hasil atau RAISERROR
pernyataan dan PRINT
.
TRY...CATCH
konstruksi dapat ditumpuk. TRY
Blok atau CATCH
blok dapat berisi konstruksi berlapisTRY...CATCH
. Misalnya, CATCH
blok dapat berisi konstruksi yang disematkan TRY...CATCH
untuk menangani kesalahan yang ditemui oleh CATCH
kode.
Kesalahan yang ditemui dalam CATCH
blok diperlakukan seperti kesalahan yang dihasilkan di tempat lain. CATCH
Jika blok berisi konstruksi berlapisTRY...CATCH
, kesalahan apa pun di blok berlapis meneruskan TRY
kontrol ke blok berlapisCATCH
. Jika tidak ada konstruksi berlapis TRY...CATCH
, kesalahan akan diteruskan kembali ke pemanggil.
TRY...CATCH
konstruksi menangkap kesalahan yang tidak tertangani dari prosedur tersimpan atau pemicu yang dijalankan oleh kode di TRY
blok. Atau, prosedur atau pemicu yang disimpan dapat berisi konstruksi mereka sendiri TRY...CATCH
untuk menangani kesalahan yang dihasilkan oleh kode mereka. Misalnya, ketika TRY
blok menjalankan prosedur tersimpan dan kesalahan terjadi dalam prosedur tersimpan, kesalahan dapat ditangani dengan cara berikut:
Jika prosedur tersimpan tidak berisi konstruksinya sendiri
TRY...CATCH
, kesalahan mengembalikan kontrol keCATCH
blok yang terkait denganTRY
blok yang berisiEXECUTE
pernyataan.Jika prosedur tersimpan berisi
TRY...CATCH
konstruksi, kesalahan mentransfer kontrol keCATCH
blok dalam prosedur tersimpan.CATCH
Ketika kode blok selesai, kontrol diteruskan kembali ke pernyataan segera setelahEXECUTE
pernyataan yang memanggil prosedur tersimpan.
GOTO
pernyataan tidak dapat digunakan untuk memasukkan TRY
atau CATCH
memblokir. GOTO
pernyataan dapat digunakan untuk melompat ke label di dalam blok atau CATCH
yang sama TRY
atau untuk meninggalkan atau TRY
CATCH
memblokir.
Konstruksi TRY...CATCH
tidak dapat digunakan dalam fungsi yang ditentukan pengguna.
Mengambil informasi kesalahan
Dalam cakupan CATCH
blok, fungsi sistem berikut dapat digunakan untuk mendapatkan informasi tentang kesalahan yang menyebabkan CATCH
blok dijalankan:
Fungsi | Deskripsi |
---|---|
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 kembali NULL
jika dipanggil di luar cakupan CATCH
blok. Informasi kesalahan dapat diambil dengan menggunakan fungsi-fungsi ini dari mana saja dalam cakupan CATCH
blok. 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 ini ERROR_*
juga berfungsi di CATCH
blok di dalam prosedur tersimpan yang dikompilasi secara asli.
Kesalahan tidak terpengaruh oleh TRY... Konstruksi CATCH
TRY...CATCH
konstruksi 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
menangani kesalahan.Perhatian, seperti permintaan yang mengganggu klien atau koneksi klien yang rusak.
Ketika administrator sistem menggunakan
KILL
pernyataan untuk mengakhiri sesi.
Jenis kesalahan berikut tidak ditangani oleh CATCH
blok ketika terjadi pada tingkat eksekusi yang sama dengan TRY...CATCH
konstruksi:
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 mengeksekusi sp_executesql
atau prosedur tersimpan yang ditentukan pengguna) di dalam TRY
blok, kesalahan terjadi pada tingkat yang lebih rendah dari TRY...CATCH
konstruksi dan akan ditangani oleh blok terkait CATCH
.
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 dijalankan di dalam prosedur tersimpan SELECT
.
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 keluar dari TRY...CATCH
konstruksi ke tingkat yang lebih tinggi berikutnya.
Menjalankan pernyataan di SELECT
dalam prosedur tersimpan menyebabkan kesalahan terjadi pada tingkat yang lebih rendah dari TRY
blok. Kesalahan 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 yang tidak dapat diterapkan
Jika kesalahan yang dihasilkan dalam TRY
blok menyebabkan status transaksi saat ini tidak valid, transaksi diklasifikasikan sebagai transaksi yang tidak dapat diterapkan. Kesalahan yang biasanya mengakhiri transaksi di luar TRY
blok menyebabkan transaksi memasuki status tidak dapat diterapkan ketika kesalahan terjadi di dalam TRY
blok. Transaksi yang tidak dapat diterapkan hanya dapat melakukan operasi baca atau ROLLBACK TRANSACTION
. 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 dikirim ke aplikasi klien. Ini menunjukkan bahwa transaksi yang tidak dapat diterapkan terdeteksi dan digulung balik.
Untuk informasi selengkapnya tentang transaksi dan fungsi yang XACT_STATE
tidak dapat diterapkan, lihat XACT_STATE.
Contoh
J. Gunakan TRY... MENANGKAP
Contoh berikut menunjukkan SELECT
pernyataan yang menghasilkan kesalahan dibagi berdasarkan 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. Gunakan 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. Gunakan 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
Konten terkait
- 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)