Saya membuat prosedur tersimpan untuk melakukan pencarian melalui tabel. Saya memiliki banyak bidang pencarian yang berbeda, semuanya opsional. Apakah ada cara untuk membuat prosedur tersimpan yang akan menangani ini? Katakanlah saya memiliki tabel dengan empat bidang: ID, FirstName, LastName, dan Judul. Saya bisa melakukan sesuatu seperti ini:
CREATE PROCEDURE spDoSearch
@FirstName varchar(25) = null,
@LastName varchar(25) = null,
@Title varchar(25) = null
AS
BEGIN
SELECT ID, FirstName, LastName, Title
FROM tblUsers
WHERE
FirstName = ISNULL(@FirstName, FirstName) AND
LastName = ISNULL(@LastName, LastName) AND
Title = ISNULL(@Title, Title)
END
Jenis pekerjaan ini. Namun itu mengabaikan catatan di mana Nama depan, Nama belakang atau Judul NULL. Jika Judul tidak ditentukan dalam parameter pencarian saya ingin memasukkan catatan di mana Judul NULL - sama untuk FirstName dan LastName. Saya tahu saya mungkin bisa melakukan ini dengan SQL dinamis tetapi saya ingin menghindarinya.
tsql
optional-parameters
Corey Burnett
sumber
sumber
code
ISNULL (FirstName, ') = ISNULL (@FirstName,' ') - ini akan membuat setiap NULL menjadi string kosong dan yang dapat dibandingkan melalui persamaan. operator. Jika Anda ingin mendapatkan semua judul jika parameter input nol, maka coba sesuatu seperti itu:code
FirstName = @FirstName ATAU @FirstName IS NULL.Jawaban:
Mengubah pencarian secara dinamis berdasarkan parameter yang diberikan adalah subjek yang rumit dan melakukannya satu arah di atas yang lain, bahkan dengan perbedaan yang sangat kecil, dapat memiliki implikasi kinerja yang sangat besar. Kuncinya adalah menggunakan indeks, abaikan kode ringkas, abaikan khawatir tentang pengulangan kode, Anda harus membuat rencana eksekusi kueri yang baik (gunakan indeks).
Baca ini dan pertimbangkan semua metode. Metode terbaik Anda akan tergantung pada parameter Anda, data Anda, skema Anda, dan penggunaan Anda yang sebenarnya:
Kondisi Pencarian Dinamis dalam T-SQL oleh oleh Erland Sommarskog
Kutukan dan Berkat dari Dynamic SQL oleh Erland Sommarskog
Jika Anda memiliki versi SQL Server 2008 yang tepat (SQL 2008 SP1 CU5 (10.0.2746) dan yang lebih baru), Anda bisa menggunakan sedikit trik ini untuk benar-benar menggunakan indeks:
Tambahkan
OPTION (RECOMPILE)
ke kueri Anda, lihat artikel Erland , dan SQL Server akan menyelesaikanOR
dari dalam(@LastName IS NULL OR LastName= @LastName)
sebelum rencana kueri dibuat berdasarkan nilai runtime dari variabel lokal, dan indeks dapat digunakan.Ini akan berfungsi untuk versi SQL Server (mengembalikan hasil yang tepat), tetapi hanya menyertakan OPSI (RECOMPILE) jika Anda menggunakan SQL 2008 SP1 CU5 (10.0.2746) dan yang lebih baru. OPSI (RECOMPILE) akan mengkompilasi ulang kueri Anda, hanya verison yang tercantum akan mengkompilasi ulang berdasarkan nilai waktu berjalan saat ini dari variabel lokal, yang akan memberi Anda kinerja terbaik. Jika tidak pada versi SQL Server 2008, biarkan saja garis itu.
sumber
Jawaban dari @ KM sejauh ini baik tetapi gagal untuk sepenuhnya menindaklanjuti salah satu nasihat awalnya;
Jika Anda mencari untuk mencapai kinerja terbaik maka Anda harus menulis permintaan khusus untuk setiap kemungkinan kombinasi kriteria opsional. Ini mungkin terdengar ekstrem, dan jika Anda memiliki banyak kriteria opsional maka mungkin saja, tetapi kinerja seringkali merupakan pertukaran antara upaya dan hasil. Dalam praktiknya, mungkin ada seperangkat kombinasi parameter umum yang dapat ditargetkan dengan kueri yang dipesan lebih dahulu, kemudian kueri umum (sesuai jawaban lain) untuk semua kombinasi lainnya.
Keuntungan dari pendekatan ini adalah bahwa dalam kasus-kasus umum yang ditangani oleh permintaan yang dipesan lebih dahulu permintaannya seefisien mungkin - tidak ada dampak dari kriteria yang tidak tersedia. Juga, indeks dan peningkatan kinerja lainnya dapat ditargetkan pada permintaan khusus yang dipesan khusus daripada mencoba untuk memenuhi semua situasi yang mungkin.
sumber
Anda dapat melakukannya dalam kasus berikut,
Namun tergantung pada data kadang-kadang lebih baik membuat permintaan dinamis dan menjalankannya.
sumber
Lima tahun terlambat ke pesta.
Disebutkan dalam tautan yang disediakan dari jawaban yang diterima, tetapi saya pikir itu layak mendapatkan jawaban eksplisit pada SO - secara dinamis membangun kueri berdasarkan parameter yang disediakan. Misalnya:
Mempersiapkan
Prosedur
Pemakaian
Pro:
Cons:
Bukan jawaban langsung, tetapi terkait dengan masalah alias gambaran besarnya
Biasanya, prosedur tersimpan penyaringan ini tidak mengambang, tetapi dipanggil dari beberapa lapisan layanan. Ini meninggalkan pilihan untuk memindahkan logika bisnis (penyaringan) dari SQL ke lapisan layanan.
Salah satu contoh adalah menggunakan LINQ2SQL untuk menghasilkan kueri berdasarkan filter yang disediakan:
Pro:
Cons:
sumber
Perpanjang
WHERE
kondisi Anda :yaitu menggabungkan berbagai kasus dengan kondisi boolean.
sumber
Ini juga berfungsi:
sumber