Katakanlah saya harus mengimplementasikan sepotong kode T-SQL yang harus mengembalikan tabel sebagai hasilnya. Saya dapat mengimplementasikan fungsi nilai tabel atau prosedur tersimpan yang mengembalikan sekumpulan baris. Apa yang harus saya gunakan?
Singkatnya, yang ingin saya ketahui adalah:
Apa perbedaan utama antara fungsi dan prosedur tersimpan? Pertimbangan apa yang harus saya pertimbangkan untuk menggunakan salah satunya?
Jawaban:
Jika Anda cenderung ingin menggabungkan hasil dari potongan kode ini dengan tabel lain, maka jelas fungsi nilai tabel akan memungkinkan Anda untuk membuat hasil dalam satu pernyataan SELECT.
Umumnya, ada hierarki (View <TV Function <Stored Proc). Anda dapat melakukan lebih banyak pada masing-masingnya, tetapi kemampuan untuk menyusun keluaran, dan agar pengoptimal benar-benar terlibat menurun seiring dengan peningkatan fungsionalitas.
Jadi gunakan salah satu yang minimal memungkinkan Anda untuk mengekspresikan hasil yang Anda inginkan.
sumber
Fungsi harus deterministik, dan tidak dapat digunakan untuk membuat perubahan pada database, sedangkan prosedur tersimpan memungkinkan Anda untuk melakukan penyisipan dan pembaruan, dll.
Anda harus membatasi penggunaan fungsi, karena fungsi tersebut menimbulkan masalah skalabilitas yang sangat besar untuk kueri yang besar dan kompleks. Mereka menjadi semacam "kotak hitam" untuk pengoptimal kueri, dan Anda akan melihat perbedaan besar dalam kinerja antara menggunakan fungsi dan cukup memasukkan kode ke dalam kueri.
Tapi mereka pasti berguna untuk pengembalian nilai tabel dalam kasus yang sangat spesifik.
Jika Anda perlu mengurai daftar yang dipisahkan koma, untuk mensimulasikan pengalihan array ke prosedur, fungsi dapat mengubah daftar menjadi tabel untuk Anda. Ini adalah praktik umum dengan Sql Server 2005, karena kita belum bisa meneruskan tabel ke prosedur tersimpan (kita bisa dengan 2008).
sumber
Dari dokumen :
sumber
Saya akan menulis beberapa perbedaan menarik antara prosedur dan fungsi yang tersimpan.
Kami tidak dapat menggunakan fungsi non deterministik dalam Fungsi tetapi kami dapat menggunakan fungsi non deterministik dalam prosedur tersimpan. Sekarang muncul pertanyaan, apa itu fungsi non deterministik .. Jawabnya: -
Pengecualian:-
Kita dapat menggunakan pernyataan DML (masukkan, perbarui, hapus) dalam prosedur tersimpan tetapi kita tidak dapat menggunakan pernyataan DML dalam fungsi pada tabel fisik atau tabel permanen. Jika kita ingin melakukan operasi DML dalam fungsi kita bisa melakukannya pada variabel tabel bukan pada tabel permanen.
Kami tidak dapat menggunakan penanganan kesalahan dalam fungsi tetapi kami dapat melakukan penanganan kesalahan dalam prosedur yang tersimpan.
sumber
Prosedur dapat mengembalikan nilai nol atau n sedangkan fungsi dapat mengembalikan satu nilai yang wajib.
Prosedur dapat memiliki parameter input / output untuk itu sedangkan fungsi hanya dapat memiliki parameter input.
Prosedur memungkinkan pilih serta pernyataan DML di dalamnya sedangkan fungsi hanya memungkinkan pernyataan pilih di dalamnya.
Fungsi dapat dipanggil dari prosedur sedangkan prosedur tidak dapat dipanggil dari fungsi.
Pengecualian dapat ditangani oleh blok coba-tangkap dalam suatu prosedur sedangkan blok coba-tangkap tidak dapat digunakan dalam suatu fungsi.
Kita bisa pergi ke manajemen transaksi dalam prosedur sedangkan kita tidak bisa berfungsi.
Prosedur tidak dapat digunakan dalam pernyataan pilih sedangkan fungsi dapat disematkan dalam pernyataan pilih.
UDF (User Defined function) dapat digunakan dalam pernyataan SQL di mana pun di bagian
WHERE
/HAVING
/SELECT
sedangkan prosedur tersimpan tidak bisa.UDF yang mengembalikan tabel dapat diperlakukan sebagai kumpulan baris lain. Ini dapat digunakan
JOIN
dengan tabel lain.UDF sebaris dapat dianggap sebagai tampilan yang mengambil parameter dan dapat digunakan dalam
JOIN
operasi kumpulan baris dan lainnya.sumber
Jika Anda memiliki sebuah fungsi, Anda dapat menggunakannya sebagai bagian dari pernyataan SQL Anda, misalnya
SELECT function_name(field1) FROM table
Ini tidak bekerja dengan cara ini untuk prosedur yang disimpan.
sumber
Saya menjalankan beberapa tes dengan sedikit logika yang berjalan lama, dengan sedikit kode yang sama (pernyataan SELECT panjang) yang berjalan di Fungsi Table Valued dan Prosedur Tersimpan, dan EXEC / SELECT lurus, dan masing-masing dilakukan secara identik.
Menurut pendapat saya, selalu gunakan Fungsi Nilai Tabel daripada prosedur tersimpan untuk mengembalikan kumpulan hasil, karena ini membuat logika lebih mudah dan dapat dibaca dalam kueri yang kemudian bergabung dengannya, dan memungkinkan Anda untuk menggunakan kembali logika yang sama. Untuk menghindari terlalu banyak hit kinerja, saya sering menggunakan parameter "opsional" (yaitu Anda dapat meneruskan NULL ke mereka) untuk mengaktifkan fungsi untuk mengembalikan hasil yang ditetapkan menjadi lebih cepat, misalnya:
CREATE FUNCTION dbo.getSitePermissions(@RegionID int, @optPersonID int, optSiteID int) AS RETURN SELECT DISTINCT SiteID, PersonID FROM dbo.SiteViewPermissions WHERE (@optPersonID IS NULL OR @optPersonID = PersonID) AND (@optSiteID IS NULL OR @optSiteID = SiteID) AND @RegionID = RegionID
Dengan cara ini Anda dapat menggunakan fungsi ini untuk banyak situasi yang berbeda, dan tidak mengalami penurunan kinerja yang besar. Saya yakin ini lebih efisien daripada memfilter sesudahnya:
SELECT * FROM dbo.getSitePermissions(@RegionID) WHERE SiteID = 1
Saya telah menggunakan teknik ini dalam beberapa fungsi, terkadang dengan daftar panjang parameter "opsional" dari jenis ini.
sumber
Saya pribadi menggunakan fungsi nilai tabel ketika semua yang saya kembalikan adalah tabel tunggal tanpa pengaruh. Pada dasarnya saya memperlakukan mereka seperti pandangan berparameter.
Jika saya memerlukan beberapa kumpulan data yang dikembalikan atau jika akan ada nilai yang diperbarui dalam tabel, saya menggunakan prosedur tersimpan.
2 sen saya
sumber
Seperti disebutkan di atas, fungsi lebih dapat dibaca / disusun / mendokumentasikan sendiri, tetapi secara umum kurang berkinerja, dan dapat menjadi sangat kurang berkinerja jika Anda terbawa dengan mereka dalam gabungan seperti
SELECT * FROM dbo.tvfVeryLargeResultset1(@myVar1) tvf1 INNER JOIN dbo.tvfVeryLargeResultset1(@myVar2) tvf2 ON (tvf1.JoinId = tvf2.JoinId)
Seringkali, Anda hanya perlu menerima redundansi kode yang dapat dihilangkan tvf (dengan biaya kinerja yang tidak dapat diterima.)
Satu hal lain yang belum saya lihat disebutkan adalah bahwa Anda tidak dapat menggunakan tabel temporer yang mengubah status database di dalam tvf multi-pernyataan. Mekanisme yang paling setara secara fungsional untuk tabel temp adalah perubahan non-status, dalam variabel tabel memori, dan untuk kumpulan data besar, tabel temp kemungkinan akan lebih berkinerja daripada variabel tabel. (Alternatif lain termasuk tabel dinamis & ekspresi nilai tabel umum, tetapi pada beberapa tingkat kerumitan, ini berhenti menjadi pilihan yang baik IMO.)
sumber
Saya akan menguji keduanya. Sepertinya pendekatan sp atau tabel turunan akan jauh lebih cepat daripada fungsi dan jika demikian pendekatan itu harus digunakan. Secara umum saya menghindari fungsi karena mereka bisa menjadi babi kinerja.
sumber
Itu tergantung :) Jika Anda ingin menggunakan hasil nilai tabel di prosedur lain, Anda lebih baik menggunakan Fungsi TableValued. Jika hasilnya untuk klien, proses yang disimpan biasanya merupakan cara yang lebih baik untuk digunakan.
sumber
Prosedur yang disimpan adalah kueri yang telah dikompilasi sebelumnya yang dieksekusi lebih cepat dan menyimpan dari injeksi sql. Mereka dapat mengembalikan nilai 0 atau N. Kami dapat melakukan operasi DML di dalam prosedur yang tersimpan. Kita bisa menggunakan fungsi di dalam prosedur dan bisa menggunakan fungsi di kueri pemilihan. Fungsi digunakan untuk mengembalikan nilai apa pun dan operasi DML tidak dimungkinkan dalam fungsi. fungsi terdiri dari dua jenis skalar dan nilai tabel. fungsi skalar mengembalikan satu nilai, fungsi bernilai tabel yang digunakan untuk mengembalikan baris tabel.
sumber