Sub-Materi: Prosedur Fungsi
Obyek dalam T-SQL dibangun untuk memenuhi kebutuhan terhadap kemudahan pemeliharaan, penyimpanan script, dan penggunaan kembali. Secara umum, ada tiga obyek T-SQL yang dipakai yaitu prosedur, fungsi, dan trigger (pemicu). Seluruh obyek T-SQL mempunyai struktur umum yang sama, yaitu terdiri dari head (kepala) dan body (tubuh). Head berisi seluruh komponen dalam pembentukan obyek, sedangkan body berisi seluruh script yang dipakai untuk proses didalam obyek tersebut.
Head diawali dengan kata kunci data definition language (DDL) yaitu create, update, dan delete. Setelah itu diikuti dengan nama obyek. Setelah nama obyek, ada komponen khusus yang mengikuti masing-masing obyek. Untuk body, tidak ada aturan khusus kecuali dimulai dengan BEGIN dan diakhiri dengan END. Kecuali untuk beberapa jenis obyek, memerlukan kata kunci tertentu sebagai syarat completeness. Pemisah antara head dan body berupa sebuah kata kunci yaitu AS.
Prosedur
Prosedur dalam T-SQL disebut sebagai Stored Procedure (SProc). Dalam istilah yang paling sederhana, prosedur adalah kumpulan dari perintah-perintah SQL yang telah di-compile, yang bisa diakses secara langsung oleh SQL Server dan aplikasi client. Prosedur memberikan fungsionalitas pemrograman dalam skala yang luas, karena prosedur mampu:
1. Mengimplementasikan view berparameter
Prosedur memiliki kemampuan untuk mengembalikan
resultset berdasarkan query. Dengan parameter (variabel
yang digunakan untuk melempar nilai), proses dalam prosedur mampu mengembalikan bermacam-macam bentuk
resultset.
2. Mengembalikan nilai scalar
Melalui parameter, prosedur mampu memberikan nilai output. Selain melalui parameter, bisa juga melalui kata kunci RETURN. Dengan adanya RETURN, perintah query setelahnya tidak akan dieksekusi. Umumnya, RETURN digunakan ketika terdapat banyak kondisi dalam prosedur. 3. Pemeliharaan data
Prosedur juga bisa digunakan untuk melakukan insert,
update, dan delete (DML).
4. Sebagai bagian dari proses bisnis
Proses bisnis berkaitan dengan pembuatan keputusan. Pengaturan alur statement menjadi hal yang mutlak disini. Baca kembali Bab 3 mengenai kontrol alur program.
Gambar 5.1 Gambaran umum prosedur
Membuat Prosedur
Pembuatan prosedur menggunakan CREATE PROCEDURE, untuk pengubahannya menggunakan ALTER PROCEDURE, dan untuk penghapusannya menggunakan DROP PROCEDURE. Lebih lengkapnya, bisa dilihat pada Kode 5.1.
Parameter dalam prosedur diperbolehkan untuk memiliki nilai awal (default). Jadi ketika prosedur dieksekusi, parameter ini tidak perlu diisi.
Kode 5.1
-- membuat prosedur
CREATE PROCEDURE <nama prosedur> [<@param1> <tipe data> [=<nilai awal>] [OUT[PUT]], ...] AS BEGIN <SQL> | <script block> RETURN <nilai> END; -- mengubah prosedur
ALTER PROCEDURE <nama prosedur>
[<@param1> <tipe data> [=<nilai awal>] [OUT[PUT]], ...] AS BEGIN <SQL> | <script block> RETURN <nilai> END; -- menghapus prosedur
DROP PROCEDURE <nama prosedur>;
Parameter dalam Prosedur
Seperti yang telah dijelaskan sebelumnya, fungsi prosedur dapat dimaksimalkan dengan adanya parameter. Parameter merupakan sebuah variabel yang digunakan sebagai alat bantu untuk memasukkan atau mengeluarkan nilai dari obyek T-SQL. Ada dua jenis parameter dalam prosedur, yaitu IN dan OUT. Parameter bertipe IN digunakan sebagai parameter input. Maksudnya adalah parameter ini hanya menerima masukan dari luar prosedur untuk kemudian dipakai didalam prosedur. Sedangkan parameter bertipe OUT digunakan sebagai output. Maksudnya adalah parameter ini hanya dipakai untuk mengeluarkan nilai dari dalam prosedur untuk dipakai oleh lingkungan tempat prosedur tersebut digunakan.
Dari kedua tipe tersebut, didalam prosedur itu sendiri, diperlakukan sama, dan digunakan selayaknya variabel pada umumnya. Secara default, parameter yang ditulis didalam pembentukan prosedur bertipe IN.
Untuk membuat parameter, bisa dilihat kembali pada Kode 5.1. Pada dasarnya, parameter membutuhkan dua hingga empat informasi:
1. Nama parameter 2. Tipe data parameter 3. Nilai default
4. Jenis parameter
Perhatikan penggalan kode program berikut:
Kode 5.2
CREATE PROCEDURE spAmbilMhsPerGender @gender CHAR(1) = 'P',
@jumlahData NUMERIC OUTPUT
...
Parameter @gender merupakan masukan bagi prosedur untuk memberikan kondisi pada pencariannya. Sedangkan @jumlahData merupakan keluaran. Untuk parameter @gender, ketika prosedur dieksekusi tanpa memberikan nilai pada parameter ini, secara default @gender bernilai P.
Eksekusi Prosedur
Seperti yang telah disebutkan sebelumnya bahwa prosedur bisa menggunakan parameter dan mampu mengembalikan nilai (parameter bertipe OUT, atau menggunakan kata kunci RETURN), maka semua elemen ini harus di-handle ketika akan mengeksekusi prosedur. Perhatikan kode program berikut ini:
Kode 5.3
CREATE PROCEDURE spAmbilMhsPerGender @gender CHAR(1) = 'P'
AS
BEGIN
SELECT * FROM mahasiswa
RETURN @@ROWCOUNT;
END;
Kode 5.4
-- Eksekusi SProc
BEGIN
DECLARE @jumlahData INT;
EXEC @jumlahData = spAmbilMhsPerGender 'W';
PRINT @jumlahData;
END;
Hasil:
nim nama alamat kota jns_kel.. sts_nikah
05390102208 Cinta Perum Pondok Nirwana Blok BC-14 Surabaya W B 06390102666 Entin Jl. Yos Sudarso 1 Sidoarjo W B ...
Pada Kode 5.3, prosedur spAmbilMhsPerGender digunakan untuk mengambil data mahasiswa yang disaring berdasarkan jenis kelamin. Karena ada penyaringan, maka prosedur harus mempunyai parameter bertipe IN yaitu @gender yang diberi nilai default P sebagai representasi dari jenis kelamin pria. Body prosedur hanya berisi perintah SELECT, sesuai dengan nama prosedur, dengan WHERE untuk penyaringan sesuai @gender. Nilai balikan (RETURN) dari prosedur ini adalah jumlah data hasil SELECT yang tersimpan dalam @@ROWCOUNT.
Untuk pemanggilan prosedur (Kode 5.4), nilai balikan harus ditampung, oleh karena itu perlu untuk membuat variabel @jumlahData yang bertipe numerik. Dengan adanya kata kunci RETURN, maka pemanggilan prosedur harus didahului dengan variabel penampung nilai RETURN diikuti dengan operator
Ketika menggunakan OUT parameter, sedikit berbeda dengan sebelumnya. Contoh kode programmnya dapat dilihat pada Kode 5.5. Dengan adanya OUT, maka nilai OUT harus ditampung kedalam variabel @jumlahData. Pemanggilan prosedur pun langsung dengan memanggil nama prosedur, diikuti parameter , lalu kata kunci OUTPUT. Untuk pemanggilan prosedur, bisa dilihat pada Kode 5.6.
Kode 5.5
CREATE PROCEDURE spAmbilMhsPerGender @gender CHAR(1) = 'P',
@jumData INT OUTPUT AS
BEGIN
SELECT * FROM mahasiswa
WHERE jns_kelamin=@gender;
-- system function tidak dapat -- dijadikan OUTPUT;
SET @jumData=@@ROWCOUNT;
END;
Kode 5.6
-- Eksekusi SProc
BEGIN
DECLARE @jumlahData INT;
EXEC spAmbilMhsPerGender
@jumData = @jumlahData OUTPUT;
PRINT @jumlahData;
END;
Hasil:
nim nama alamat kota jns_kel.. sts_nikah
05410104001 Alif Jl. Jagir 20 Surabaya P B ...
Pemeliharaan Data
Contoh-contoh sebelumnya merupakan contoh untuk prosedur sebagai view berparameter dan prosedur yang mengembalikan nilai skalar. Untuk pemeliharaan data, prosedur memberikan kemudahan bagi pengembang aplikasi untuk melakukan
perubahan data tanpa menggunakan DML secara langsung. Dengan begitu, universalitas kode bisa tercapai.
Namun, semua ini ada pengorbanan untuk pembuatan prosedur yang lumayan panjang. Kenapa? Karena dalam DML, seluruh kolom bisa dimanipulasi. Bagian-bagian yang dimanipulasi ini harus menjadi parameter dalam prosedur. Jadi, kalau ada 50 kolom, maka prosedur memiliki 50 parameter dengan tipe IN. Berikut ini contoh prosedur untuk memasukkan data kedalam tabel dosen.
Kode 5.7
CREATE PROCEDURE spInsertDosen @nid CHAR(6),
@nama VARCHAR(100)
AS BEGIN
INSERT INTO dosen(nid, nama)
VALUES (@nid, @nama);
END;
Kode 5.8
-- Eksekusi SProc
EXEC spInsertDosen '100110', 'Tegar';
Fungsi
Bersama dengan operator, fungsi mampu memberikan kekuatan tersendiri dalam SQL. Salah satu yang sering dipakai adalah aggregate function, yaitu fungsi yang melakukan perhitungan agregasi dan menghasilkan nilai skalar. Fungsi-fungsi agregasi ini antara lain AVG(), MAX(), MIN(), COUNT(), dan SUM().
Pada Bab 1, telah dipelajari mengenai system function dalam sub-bab SQL Function. Selain fungsi agregasi, beberapa fungsi lainnya, antara lain konversi yang menggunakan CAST() dan CONVERT(); manipulasi string dengan fungsi-fungsi kerennya seperti SUBSTRING(), LEN(), REPLACE(), dll; fungsi matematika seperti CEILING(),
ROUND(), POWER(), dll; fungsi date and time yang menggunakan GETDATE(), DATEPART(), DATEADD(), dan DATEDIFF(); dan beberapa fungsi lainnya.
User-Defined Function
User-defined Function (UDF) merupakan kumpulan script yang dioptimasi dan di-compile dan dapat dipanggil untuk bekerja sebagai unit tunggal. Dalam buku ini, untuk kemudahan, maka UDF disebut juga sebagai fungsi. Fungsi dapat mengembalikan nilai apapun. Sehingga dari nilai ini, fungsi dapat dibagi menjadi 2 yaitu (1) fungsi yang mengembalikan nilai skalar (scalar-valued
Function), dan (2) fungsi yang mengembalikan nilai dalam
bentuk tabel (table-valued Function). Scalar-valued Function
Tipe ini merupakan tipe yang paling umum. Seperti yang disebutkan sebelumnya, bahwa fungsi tidak terbatas pada nilai balikan berupa integer, bahkan fungsi pun mampu mengembalikan user-defined datatypes (tipe data yang didefinisikan sendiri oleh programmer). Namun, fungsi tidak mampu mengembalikan tipe data tertentu antara lain BLOB,
cursor, dan tipestamp. Sintak untuk membuat fungsi bernilai
skalar, dapat dilihat pada Kode 5.9.
Pada Kode 5.9 dapat dilihat bahwa fungsi juga memiliki parameter seperti prosedur. Perbedaannya adalah pada tipe parameter, yang dimiliki oleh fungsi hanyalah parameter sebagai masukan. Setiap fungsi harus mengembalikan nilai, oleh karena itu kata kunci RETURNS dan RETURN harus ada didalam struktur pembuatan fungsi.
Sebagai contoh pembuatan fungsi bernilai skalar, coba lihat kembali contoh permasalahan pada cursor di Bab 4, Kode 4.11. Pada query tersebut, ada pengecekan terhadap status kelulusan mahasiswa. Kita akan coba membuat sebuah fungsi untuk pengecekan ini. Perhatikan Kode 5.10.
Kode 5.9
-- membuat prosedur
CREATE FUNCTION <nama function> ([<@param1> <tipe data>, ...]) RETURNS <tipe data> AS
BEGIN
<SQL> | <script block> RETURN <nilai>
END;
-- membuat prosedur
ALTER FUNCTION <nama function> (<@param1> <tipe data>, ...) RETURNS <tipe data> AS BEGIN
<SQL> | <script block> RETURN <nilai>
END;
-- membuat prosedur
DROP FUNCTION <nama function>;
Kode 5.10
CREATE FUNCTION Kelulusan (@nilai INT)
RETURNS VARCHAR(100)
AS BEGIN
DECLARE @lulus VARCHAR(100);
IF @nilai>55
SET @lulus = 'Lulus';
ELSE
SET @lulus = 'Gagal';
RETURN @lulus;
END;
Sehingga dari contoh query pada Kode 4.11, kode program untuk membuat cNilai diganti menjadi:
Kode 5.11
DECLARE cNilai CURSOR FOR
SELECT nama, tugas*0.4 + uts*0.3 + uas*0.3,
dbo.Kelulusan(tugas*0.4 + uts*0.3 +
uas*0.3)
FROM nilai n JOIN mk
ON n.kode_mk = mk.kode_mk
Apa yang bisa disimpulkan tentang penulisan kode program pada Kode 5.11 setelah adanya fungsi?
Ya, benar. Script menjadi lebih sederhana, dan tentunya fungsi yang telah dibuat dapat dipakai kembali di script lainnya. Perhatikan pemanggilan fungsi yang harus diikuti oleh dbo.. Hal ini dikarenakan yang membuat fungsi isLulus adalah user dengan
schema dbo..
Table-valued Function
Ada beberapa studi kasus yang memerlukan fungsi yang mampu mengembalikan sebuah tabel entah itu hasil query atau melalui proses yang sangat panjang. Pemakaian fungsi seperti ini ibarat sebuah inline view. Untuk dapat mengeksekusi fungsi jenis ini, pemanggilannya harus didalam kata kunci FROM dalam struktur
query. Sintak untuk membuat fungsi bernilai tabel, dapat dilihat
pada .
Kode 5.12
CREATE FUNCTION <nama function> (<@param1><tipe data>, ...) RETURNS TABLE |
<nama var> TABLE (<column list>) AS BEGIN
<SQL> | <script block> RETURN <perintah select> END;
Tidak ada perbedaan dengan scalar-valued function, kecuali pada bagian RETURNS. Jika pada scalar-valued function nilai RETURNS adalah tipe data, maka pada table-valued function nilai RETURNS adalah juga (sebuah variabel bertipe) tabel.
Kode 5.13
CREATE FUNCTION fnMhs(@kota VARCHAR(50))
RETURNS TABLE AS
RETURN (SELECT nim, nama, alamat, kota,
jns_kelamin, sts_nikah FROM mahasiswa
Sebagai contoh pada Kode 5.13, misal Kabag AAK ingin mengetahui seluruh data mahasiswa per kota sesuai dengan masukan. Karena ada sebuah penyaringan data berdasarkan kota, maka fungsi yang dibuat harus memiliki parameter, setidaknya satu, untuk menampung nilai penyaringan. Sedangkan untuk memanggilannya, perhatikan Kode 5.14:
Kode 5.14
SELECT *
FROM dbo.fnMhs('Surabaya'); Deterministic Function
Deterministic dan non-deterministic ditentukan oleh apa yang
dilakukan oleh fungsi. Ketika fungsi diberikan input dan selalu mengembalikan nilai yang sama, maka fungsi tersebut
deterministic. Bandingkan dengan GETDATE() yang selalu berubah setiap millisecond. GETDATE() merupakan fungsi
non-deterministic.
Agar fungsi dapat disebut sebagai deterministic, ada empat kriteria:
1. Fungsi tersebut harus terikat pada schema tertentu (WITH SCHEMABINDING).
2. Semua fungsi yang dipanggil oleh fungsi ini harus
deterministic.
3. Penggunaan tabel harus didefinisikan didalam fungsi itu sendiri.
4. Tidak adanya prosedur extended.
Dari 4 ini, ada sebuah cara (dalam SQL Server) untuk melihat apakah fungsi termasuk deterministic atau tidak, dengan menjalankan perintah berikut:
Kode 5.15
SELECT
OBJECTPROPERTY(OBJECT_ID('isLulus'),
Dari hasil perintah tersebut, fungsi isLulus ternyata
non-deterministic. Hal ini dikarenakan poin pertama, yaitu tidak
Latihan
1. Buat prosedur untuk menampilkan nim, nama, dan alamat mahasiswa sesuai angkatan. Nilai angkatan ditampung dalam parameter masukan.
2. Buat prosedur untuk menambah data mahasiswa. Seluruh nilai kolom di tabel mahasiswa ditampung dalam parameter masukan.
3. Buat prosedur untuk menghapus data mahasiswa sesuai nim. Nim ditampung dalam parameter masukan.
4. Buat fungsi untuk menghitung umur mahasiswa. Parameter masukan berupa tanggal lahir, sedangkan nilai balikan berupa umur dalam ukuran tahun.
5. Buat fungsi untuk menentukan apakah mahasiswa sudah menikah atau belum dilihat dari standar umur yang ditetapkan pemerintah.
Usia minimum pria menikah = 24 tahun. Usia minimum wanita menikah = 21 tahun.
Parameter masukan berupa tanggal lahir. Saran: gunakan fungsi yang dibuat pada no.3 untuk menghitung umur. Nilai balikan dari fungsi ini berupa status menikah yaitu B untuk belum menikah, dan M untuk sudah menikah.