Fungsi dan prosedur yang tersimpan melayani tujuan yang terpisah. Meskipun itu bukan analogi terbaik, fungsi dapat dilihat secara harfiah sebagai fungsi lain yang akan Anda gunakan dalam bahasa pemrograman apa pun, tetapi procs yang disimpan lebih seperti program individual atau skrip batch.
Fungsi biasanya memiliki output dan input opsional. Output kemudian dapat digunakan sebagai input ke fungsi lain (built-in SQL Server seperti DATEDIFF, LEN, dll) atau sebagai predikat ke SQL Query - misalnya, SELECT a, b, dbo.MyFunction(c) FROM table
atau SELECT a, b, c FROM table WHERE a = dbo.MyFunc(c)
.
Procs tersimpan digunakan untuk mengikat query SQL bersama dalam suatu transaksi, dan antarmuka dengan dunia luar. Kerangka kerja seperti ADO.NET, dll. Tidak dapat memanggil fungsi secara langsung, tetapi mereka dapat memanggil proc yang disimpan secara langsung.
Fungsi memang memiliki bahaya tersembunyi: mereka dapat disalahgunakan dan menyebabkan masalah kinerja yang agak buruk: pertimbangkan pertanyaan ini:
SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2)
Di mana MyFunction dinyatakan sebagai:
CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER
AS
BEGIN
DECLARE @retval INTEGER
SELECT localValue
FROM dbo.localToNationalMapTable
WHERE nationalValue = @someValue
RETURN @retval
END
Apa yang terjadi di sini adalah bahwa fungsi MyFunction dipanggil untuk setiap baris dalam tabel MyTable. Jika MyTable memiliki 1000 baris, maka itu adalah 1000 permintaan ad-hoc terhadap database. Demikian pula, jika fungsi dipanggil saat ditentukan dalam spesifikasi kolom, maka fungsi akan dipanggil untuk setiap baris yang dikembalikan oleh SELECT.
Jadi Anda memang harus hati-hati menulis fungsi. Jika Anda melakukan SELECT dari tabel dalam suatu fungsi, Anda perlu bertanya pada diri sendiri apakah itu bisa lebih baik dilakukan dengan GABUNG di induk yang disimpan proc atau beberapa konstruksi SQL lainnya (seperti KASUS ... KAPAN ... KETIKA ... LAIN ... AKHIR).