Saya sedang menulis fungsi yang ditentukan pengguna dalam SQL Server 2008. Saya tahu bahwa fungsi tidak dapat meningkatkan kesalahan dengan cara biasa - jika Anda mencoba memasukkan pernyataan RAISERROR, SQL akan dikembalikan:
Msg 443, Level 16, State 14, Procedure ..., Line ...
Invalid use of a side-effecting operator 'RAISERROR' within a function.
Tetapi faktanya, fungsi mengambil beberapa input, yang mungkin tidak valid dan, jika ada, tidak ada nilai yang berarti fungsi dapat kembali. Apa yang harus saya lakukan?
Saya bisa, tentu saja, mengembalikan NULL, tetapi akan sulit bagi pengembang mana pun yang menggunakan fungsi untuk memecahkan masalah ini. Saya juga bisa menyebabkan pembagian dengan nol atau sesuatu seperti itu - ini akan menghasilkan pesan kesalahan, tetapi salah kaprah. Apakah ada cara agar pesan kesalahan saya sendiri dilaporkan?
declare @error int; set @error = 'Error happened here.';
Trik yang biasa adalah memaksa pembagian dengan 0. Ini akan menimbulkan kesalahan dan mengganggu pernyataan saat ini yang mengevaluasi fungsi. Jika pengembang atau orang yang mendukung tahu tentang perilaku ini, menyelidiki dan memecahkan masalah masalahnya cukup mudah karena kesalahan pembagian oleh 0 dipahami sebagai gejala dari masalah yang berbeda, yang tidak terkait.
Seburuk ini terlihat dari sudut pandang manapun, sayangnya desain fungsi SQL saat ini tidak memungkinkan pilihan yang lebih baik. Menggunakan RAISERROR harus benar-benar diizinkan dalam fungsi.
sumber
Sebagai lanjutan dari jawaban Vladimir Korolev, idiom untuk membuang kesalahan secara kondisional adalah
sumber
Saya pikir cara terbersih adalah dengan hanya menerima bahwa fungsi dapat mengembalikan NULL jika argumen yang tidak valid dilewatkan. Selama ini jelas didokumentasikan maka ini harus baik-baik saja?
sumber
RAISEERROR
atau@@ERROR
tidak diizinkan di UDF. Bisakah Anda mengubah UDF menjadi prosedur bertingkat?Dari artikel Erland Sommarskog Penanganan Kesalahan di SQL Server - Latar Belakang :
sumber
Jawaban teratas umumnya adalah yang terbaik, tetapi tidak berfungsi untuk fungsi bernilai tabel inline.
MikeTeeVee memberikan solusi untuk ini dalam komentarnya pada jawaban atas, tetapi diperlukan penggunaan fungsi agregat seperti MAX, yang tidak bekerja dengan baik untuk keadaan saya.
Saya main-main dengan solusi alternatif untuk kasus di mana Anda memerlukan tabel inline bernilai udf yang mengembalikan sesuatu seperti select * bukan agregat. Contoh kode yang memecahkan kasus khusus ini ada di bawah ini. Seperti yang telah ditunjukkan oleh seseorang ... "JEEZ wotta hack" :) Saya menyambut solusi yang lebih baik untuk kasus ini!
sumber
Beberapa orang bertanya tentang meningkatkan kesalahan dalam fungsi Table-Valued, karena Anda tidak dapat menggunakan hal-hal " RETURN [pemain tidak valid] ". Menetapkan pemain tidak valid ke variabel berfungsi juga.
Ini menghasilkan:
sumber
Saya tidak bisa berkomentar di bawah jawaban davec mengenai fungsi nilai tabel, tetapi menurut pendapat saya ini adalah solusi yang lebih mudah:
sumber
Salah satu cara (peretasan) adalah memiliki fungsi / prosedur tersimpan yang melakukan tindakan yang tidak valid. Misalnya, pseudo SQL berikut
Dimana pada tabel tbl_throw_error, ada batasan unik pada kolom err_msg. Efek sampingnya (setidaknya pada MySQL), adalah nilai err_msg digunakan sebagai deskripsi pengecualian ketika ia kembali ke objek pengecualian level aplikasi.
Saya tidak tahu apakah Anda dapat melakukan sesuatu yang mirip dengan SQL Server, tetapi patut dicoba.
sumber