Draft Modul Pemrograman Basis Data S1 Sistem Informasi - v3 PDF
Draft Modul Pemrograman Basis Data S1 Sistem Informasi - v3 PDF
Modul Praktikum
Pemrograman
Basis Data
Program Studi S1 Sistem Informasi
Daftar Isi
Forewords… .................................................................................................................................. iv
LOOPING ............................................................................................................................. 12
PRACTICE................................................................................................................................ 18
PRACTICE................................................................................................................................ 32
PRACTICE................................................................................................................................ 50
BAB 4 PROCEDURE................................................................................................................... 52
PRACTICE................................................................................................................................ 66
PRACTICE................................................................................................................................ 79
PRACTICE................................................................................................................................ 88
PRACTICE................................................................................................................................ 93
PRACTICE................................................................................................................................ 96
DATASET................................................................................................................................. 98
DATATABLE ........................................................................................................................... 98
PRACTICE................................................................................................................................ 99
BAB 10 USING T-SQL OBJECT WITH VISUAL BASIC .NET ............................................ 100
PRACTICE.............................................................................................................................. 102
Forewords…
Kami, para laboran di Laboratorium Komputer Stikom Surabaya, tidak pernah menutup pintu
untuk pertanyaan terkait laboratorium atau terkait praktikum, jadi jangan “malu bertanya” agar
anda tidak “sesat di jalan”.
Janganlah takut dan sungkan ketika bertanya, karena kami juga akan selalu berusaha menjawab
pertanyaan dari anda.
Berbahagialah ketika soal itu mudah, tetapi janganlah mundur ketika soal itu anda anggap sulit,
karena setiap soal adalah pembuktian bahwa anda layak lulus dari praktikum atau mata kuliah
yang anda ambil.
Buktikanlah bahwa anda bisa berusaha untuk lulus dengan usaha sendiri, tidak dengan menjiplak
orang lain, karena belajar itu menyulitkan, tetapi tidak pernah merugikan. Ketika anda
mengerjakan setiap soal sendirian, maka anda membuktikan bahwa anda memiliki daya juang
untuk lulus, bukan hanya asal mengikut pada orang yang mungkin menjatuhkan anda.
Memberikan jawaban pada teman, bukanlah cara yang baik untuk membantu teman anda.
Belajarlah bersama, agar anda dan teman anda sama-sama paham dan mengerti, karena
memberikan jawaban pada teman membuat teman anda terlihat bodoh dan terkesan tidak mau
berusaha.
Jangan selalu percaya pada teman, bertanyalah pada orang yang tepat agar anda mendapatkan
jawaban yang tepat juga. Banyak terjadi terlalu percaya pada teman yang akhirnya menyebabkan
kegagalan. Pertanyaannya, apakah itu yang anda inginkan?
Bagi anda yang tidak ada keniatan dengan ilmu komputer, tetapi sudah masuk ke tempat ini,
anggaplah tempat itu sebagai batu loncatan ke tempat tujuan anda yang sebenarnya. Buktikanlah
bahwa anda masih bisa berdiri tegak, meskipun kesulitan menghadang di hadapan anda.
DOSEN
NID = NID
NID V ARCHA R2(6)
NAMA_DOSEN V ARCHA R2(100)
MAHASISWA
NILA I
NIM CHA R(11)
KODE_PRODI V ARCHA R2(5) KODE_MK V ARCHA R2(5)
NAMA_DEPA N V ARCHA R2(50) NID V ARCHA R2(6) NID = NID
MAHASISWA_BERPRESTA SI NIM = NIM NIM = NIM NIM CHA R(11)
NAMA_BELA KA NG V ARCHA R2(50)
NIM CHA R(11) A LA MA T_TINGGAL V ARCHA R2(150) TUGAS NUMBER(3) PLOTTING_A JA R
NAMA_LENGKA P V ARCHA R2(50) NIM = NIM KOTA_TINGGA L V ARCHA R2(30) UTS NUMBER(3)
KODE_MK V ARCHA R2(5)
NO_TELP V ARCHA R2(15) UAS NUMBER(3)
NO_TELP_A KTIF V ARCHA R2(15) NID V ARCHA R2(6)
PERIODE_TA HUN V ARCHA R2(10)
TGL_LA HIR DATE ID_PLOTTING V ARCHA R2(5)
JENIS_KELA MIN CHA R(1) JAM_MULA I V ARCHA R2(5)
STA TUS_NIKAH CHA R(1) JAM_SELESAI V ARCHA R2(5)
STA TUS_MHS CHA R(1) HARI V ARCHA R2(6)
KODE_MK = MK_SYARAT
LOCATIONS
COUNTRIES
LOCATION_ID <undef ined>
COUNTRY_ID <undef ined>
COUNTRY_ID <undef ined>
COUNTRY_ID = COUNTRY_ID
REGION_ID <undef ined>
STREET_ADDRESS <undef ined>
COUNTRY_NAME <undef ined>
POSTAL_CODE <undef ined>
CITY <undef ined> REGION_ID = REGION_ID
STA TE_PROVINCE <undef ined>
REGION
LOCATION_ID = LOCATION_ID
REGION_ID <undef ined>
REGION_NA ME <undef ined>
DEPA RTMENTS
DEPARTMENT_ID = DEPARTMENT_ID DEPA RTMENT_ID <undef ined>
LOCATION_ID <undef ined>
MANAGER_ID <undef ined>
DEPA RTMENT_NAME <undef ined>
JOB_HISTORY
JOB_ID <undef ined> EMPLOYEE_ID = MANAGER_ID
EMPLOY EE_ID <undef ined> DEPARTMENT_ID = DEPARTMENT_ID
DEPA RTMENT_ID <undef ined>
STA RT_DA TE DATE EMPLOY EES
END_DA TE DATE EMPLOY EE_ID <undef ined>
MANAGER_ID <undef ined>
DEPA RTMENT_ID <undef ined>
JOB_ID <undef ined>
FIRST_NAME <undef ined>
EMPLOYEE_ID = MANAGER_ID
LAST_NAME <undef ined>
EMPLOYEE_ID = EMPLOYEE_ID EMA IL <undef ined>
PHONE_NUMBER <undef ined>
HIRE_DA TE <undef ined>
SALARY <undef ined>
COMMISSION_PCT <undef ined>
JOB_ID = JOB_ID
JOBS
JOB_ID <undef ined>
JOB_TITLE <undef ined>
JOB_ID = JOB_ID
MIN_SA LARY <undef ined>
MAX_SA LA RY <undef ined>
BAB 1
INTRODUCTION TO TRANSACT-SQL
TRANSACT-SQL BLOCK
Selama pembelajaran pada matapraktikum Desain Basis Data, anda sudah menggunakan
perintah SQL untuk melakukan manipulasi dan definisi struktur tabel dan data. Pada
matapraktikum Pemrograman Basis Data, anda akan mempelajari penggunaan SQL (disebut
sebagai T-SQL pada SQL Server) untuk melakukan pemrograman pada basis data.
Sebagai satu kesatuan blok logika, skrip pemrograman dengan menggunakan T-SQL selalu
diawali dengan kata kunci BEGIN dan diakhiri dengan kata kunci END, seperti pada contoh
berikut:
BEGIN
DECLARE @nilai NUMERIC;
SET @nilai = (SELECT MAX(uas) FROM nilai);
SELECT @@ROWCOUNT;
SELECT @nilai;
END
END;
Kode 1.1 Contoh blok logika pada T-SQL
Penggunaan kata kunci BEGIN dan END identik dengan penggunaan kurung kurawal {}
pada pemrograman JAVA, dan dapat dituliskan secara bersarang (nested), seperti contoh berikut:
BEGIN
DECLARE @NAMA VARCHAR(30);
BEGIN
SET @NAMA = (SELECT FIRST_NAME + ' ' + LAST_NAME FROM EMPLOYEES WHERE
EMPLOYEE_ID = 100);
PRINT @NAMA
END;
END;
Skrip kode 1.2 akan mencetak tulisan nama lengkap karyawan dengan ID karyawan
(EMPLOYEE_ID) 100, sebagai berikut:
Seperti contoh pada kode 1.1 dan 1.2, terdapat 2 (dua) cara untuk menampilkan tulisan atau
mencetak nilai pada T-SQL. Cara pertama dengan menggunakan SELECT, dan cara kedua
menggunakan PRINT. Berikut adalah contoh penggunaan SELECT dan PRINT untuk mencetak
nilai pada T-SQL, sekaligus dengan perbedaannya.
Deklarasi Variabel
Dalam T-SQL cara pembuatan variabel diawali dengan menuliskan kata kunci DECLARE
diikuti dengan nama variabel (sebagai identitas) lalu tipe data (sebagai penentu nilai yang dapat
disimpan oleh variabel tersebut). Ada beberapa peraturan yang harus dipenuhi pada saat
mendeklarasikan variabel.
Pada saat nama variabel dituliskan, HARUS diawali dengan 1 simbol ‘@’.
Nama variabel tidak boleh memiliki spasi, dapat digantikan dengan underscore (‘_’), dan
tidak boleh diawali dengan angka.
Pada saat tipe data dituliskan, HARUS dituliskan juga jumlah karakter/digit yang dapat
ditampung, jika memungkinkan. Terdapat tipe data yang tidak membutuhkan jumlah karakter
yang dapat ditampung, salah satunya BOOLEAN.
Jika banyak variabel dibuat/dideklarasikan, maka tiap variabel dipisahkan dengan koma atau
dapat dipisahkan dengan mengganti garis kode.
Berikut adalah contoh lain pendeklarasian variabel pada T-SQL.
Tipe Data
Seperti yang telah dijelaskan sebelumnya, variabel sangat erat hubungannya dengan tipe
data. Tipe data merupakan bagian dari variabel yang mempengaruhi perilaku variabel. Dengan
tipe data ini, bisa ditentukan nilai apa yang bisa disimpan didalam variabel tersebut. Dan satu
variabel hanya bisa diberi satu tipe data.
Ada lima jenis tipe data sesuai dengan SQL-ANSI 1993 yaitu character string, numeric,
temporal, binary, dan boolean. Tidak semua provider basis data memiliki seluruh jenis tipe data.
Berikut adalah beberapa tipe data umum yang dapat digunakan pada pemrograman T-SQL:
Sebagai catatan, masih banyak tipe data lain yang disediakan oleh SQL Server dan beberapa tipe
data yang disebutkan di atas belum semuanya, hanya yang umum dipakai saja.
Menggunakan Variabel
Sebelum membahas tentang penggunaan variabel, pertama-tama perlu dijelaskan terlebih
dulu bagaimana mengisikan nilai ke dalam sebuah variabel. Ada dua cara yang dapat digunakan
untuk memberikan nilai pada variabel, yaitu:
SET
SELECT
Seperti contoh sebelumnya, sebuah variabel juga dapat langsung diisi dengan nilai pada saat
variabel tersebut dideklarasikan.
Karena pemrograman dilakukan di dalam basis data, maka variabel dapat diisi
dengan/tanpa memanfaatkan data yang ada pada tabel. Ketika sebuah variabel akan diisi dengan
nilai dari tabel, maka harus dipastikan bahwa query SELECT yang digunakan HARUS
menghasilkan 1 (satu) baris. Berikut adalah beberapa contoh untuk melakukan pemasukan nilai
ke dalam variabel.
BEGIN
-- penggunaan SET untuk mengisi variabel
DECLARE @var VARCHAR(50);
SET @var = 'STIKOM SURABAYA';
Catatan:
Pada saat menggunakan SET yang dikombinasi dengan perintah SELECT untuk mengisi
variabel, HARUS dipastikan bahwa perintah SELECT harus mengembalikan 1 nilai (1 baris
dan 1 kolom), sepert contoh di atas.
Pada saat menggunakan SELECT (tanpa SET) untuk mengisi variabel, HARUS dipastikan
bahwa perintah SELECT harus mengembalikan 1 baris. jumlah kolom tergantung pada
berapa variabel yang akan diisi dari perintah SELECT tersebut.
Setelah (atau sebelum) variabel memiliki nilai, terdapat beberapa operasi yang dapat
digunakan pada variabel, diantaranya:
1. Operasi aritmatika: Operasi ini berupa penambahan, pengurangan, perkalian, pembagian,
atau operasi matematis lain.
2. Operasi konkatenasi: Operasi ini berupa penggabungan 2 buah nilai agar menjadi 1 nilai.
Dapat berupa penggabungan tulisan dengan tulisan, angka dengan tulisan, dll.
3. Operasi logika: Operasi ini berupa pemakaian variabel untuk proses logis. Proses logis dapat
mengandung kalimat pengendalian arus program (control flow statement), yaitu percabangan
dan perulangan.
Contoh operasi logika akan ditunjukkan pada penjelasan sub bab control flow statement,
sedangkan contoh operasi aritmatika dan operasi konkatenasi dapat dilihat pada contoh-contoh
berikut:
SET @a = 20
SET @b = @a + 50
Seperti yang terlihat pada Gambar 1.3, jika tipe data angka pertama tidak mampu
menangani angka desimal, maka nilai desimal akan dari hasil akan dihilangkan (bukan
dibulatkan), sebaliknya jika tipe data angka yang pertama mampu menangani angka decimal,
maka nilai desimal akan ditampilkan (hasil pengkodean kedua dan ketiga).
Sedangkan untuk operasi konkatenasi, terdapat catatan pada saat terjadi penggabungan
antara tipe data karakter (text) dengan tipe data lain, yaitu pada saat menggabungkan tipe data
karakter dengan tipe data lain, maka tipe data lain selain karakter HARUS dirubah menjadi
tipe data karakter. Perubahan tipe data dari sebuah nilai dapat dilakukan dengan memanfaatkan
perintah/fungsi CONVERT yang sudah ada pada SQL Server. Berikut adalah 2 contoh
penerapan operasi konkatenasi.
Seperti yang dicontohkan pada kode 1.7, terdapat tambahan fungsi CONVERT agar variabel
@jml dengan tipe INT dapat digabungkan dengan tulisan “Jumlah Karyawan = “.
CONDITIONAL FLOW
Secara analogi dalam kehidupan sehari-hari, percabangan dapat dilihat ketika seseorang
berjalan dan bertemu dengan persimpangan. Disini, ada beberapa pilihan yang bisa dibuat,
apakah belok ke kanan, ke kiri, atau lurus? Ada juga pertimbangan-pertimbangan seperti, apa-
kah lebih jauh, jalannya rusak, atau yang lainnya dalam setiap pilihan jalan.
Pembuatan program tidak hanya membuat terdiri dari statement/perintah yang dijalankan
secara urut dari baris pertama sampai terakhir. Ada beberapa statement yang mungkin
membutuhkan kondisi tertentu. Kondisi ini didalam program disebut sebagai percabangan.
Dalam T-SQL, hanya ada satu kata kunci untuk percabangan, yaitu IF..ELSE. Secara
sederhana, struktur penulisan percabangan dengan IF..ELSE adalah sebagai berikut:
IF <kondisi boolean>
BEGIN
SQL | <script block>
END
[ELSE [IF <kondisi boolean>]
[BEGIN
SQL | <script block>]
END]
[ELSE [IF <kondisi boolean>]
[BEGIN
SQL | <script block>]
END] | <script block>]
Setiap percabangan membutuhkan kondisi. Dalam arti kata lain, setiap kata kunci IF diikuti
oleh kondisi. Kondisi ini adalah kondisi yang bernilai BOOLEAN, dengan kata lain, kondisi
yang bisa terpenuhi secara total atau tidak terpenuhi sama sekali. Penulisan kondisi boolean pada
IF sama seperti penulisan kondisi data pada klausa WHERE atau HAVING pada perintah SQL
SELECT. Penggambaran alur dari proses percabangan dapat dilihat pada gambar berikut.
DECLARE @N INT = 55
IF @N%2 = 0
--jika sisa bagi 2 adalah 0, maka angka genap
BEGIN
PRINT 'ANGKA ADALAH BILANGAN GENAP'
END
ELSE IF @N%2 > 0
--jika sisa bagi 2 bukan 0, maka angka ganjil
BEGIN
PRINT 'ANGKA ADALAH BILANGAN GANJIL'
END
Berdasarkan contoh kode 1.9, terdapat variabel @N, yang diperiksa apakah berisi angka genap
atau tidak. Pemeriksaan dilakukan dengan cara memeriksa sisa bagi dari angka dengan dibagi
angka 2, jika sisa bagi adalah 0, maka angka tersebut adalah angka genap, sebaliknya, jika sisa
bagi bukan 0, maka angka adalah angka ganjil.
Contoh lain penerapan percabangan adalah untuk menentukan apakah sebuah tahun adalah
tahun kabisat atau bukan. Untuk menentukan apakah sebuah tahun merupakan kabisat atau tidak,
terdapat beberapa kondisi yang harus dipenuhi. Pada contoh ini, hanya ada 2 kondisi yang akan
digunakan, yaitu jika angka tahun habis jika dibagi dengan angka 400, dan jika angka tahun
memiliki sisa bagi jika dibagi 400, tetapi habis jika dibagi dengan 4. Pengkodean dituliskan pada
halaman berikutnya.
IF @TAHUN%400 = 0
BEGIN
PRINT 'INI ADALAH TAHUN KABISAT'
END
ELSE IF @TAHUN%400 <> 0 AND @TAHUN%4 = 0
BEGIN
PRINT 'INI ADALAH TAHUN KABISAT'
END
ELSE
BEGIN
PRINT 'INI BUKAN TAHUN KABISAT'
END
LOOPING
Adakalanya pada pemrograman, ada proses atau perintah yang harus dijalankan berulang-
ulang. Contoh, untuk mencetak angka dari 1 sampai dengan 5 dapat dilakukan dengan pengkodean
seperti berikut:
BEGIN
PRINT '1';
PRINT '2';
PRINT '3';
PRINT '4';
PRINT '5';
END
Kode 1.11 di atas adalah efektif karena dapat memenuhi kebutuhan untuk mencetak angka dari 1
sampai 5, tetapi cara ini tidaklah efisien, karena ada 1 perintah yang sama, yaitu PRINT, yang
dituliskan sebanyak 5 kali. Bagaimana jika angka yang dicetak lebih banyak, misal 1 sampai
dengan 100? Bagaimana jika proses yang dilakukan berulang-ulang tidak hanya melakukan cetak,
tetapi terdiri dari 2 atau lebih baris kode, seperti perhitungan, atau bahkan percabangan?
Untuk dapat mencapai efisiensi dalam pengerjaan kode program, ada sebuah konsep yang
disebut dengan perulangan (looping). Dengan perulangan, sebuah proses yang harus dijalankan
berulang kali, cukup dituliskan satu kali saja, tetapi akan dapat menghasilkan hasil yang sama
dengan kode 1.11. Pada T-SQL, perulangan dilakukan dengan menggunakan perintah WHILE.
Struktur perintah WHILE adalah sebagai berikut:
Cara kerja WHILE, sesuai dengan kode 1.12, adalah melakukan pengecekan terlebih dahulu
pada kondisi BOOLEAN. Selama kondisi bernilai TRUE, maka WHILE akan dijalankan, dan
sebaliknya, ketika kondisi bernilai FALSE, maka WHILE tidak akan dijalankan. Secara
sederhana, alur kerja perulangan dapat dilihat pada gambar 1.7.
Dalam menjalankan blok WHILE, program melakukan pengecekan terhadap dua buah kata
kunci, yaitu BREAK, dan CONTINUE. Kata kunci BREAK digunakan untuk keluar dari
perulangan tanpa harus menunggu seluruh blok dijalankan/sebelum perulangan selesai secara
normal. Hal ini bisa dilakukan dengan menambahkan kondisi sebelum kata kunci BREAK. Dari
kode 1.12, dengan munculnya BREAK, maka <script2> dan <script3> tidak akan dijalankan.
Sedangkan kata kunci CONTINUE digunakan untuk mengembalikan perulangan ke posisi awal
<script1>. Kata kunci CONTINUE umumnya digunakan untuk re-evaluasi kondisi. Hal ini bisa
dilakukan dengan menambahkan kondisi sebelum kata kunci CONTINUE. Dari kode 1.12,
dengan munculnya CONTINUE, maka <script3> tidak akan dijalankan.
Berikut adalah bentuk perulangan dari kode 1.11, lengkap dengan keterangan looping.
BEGIN
DECLARE @N INT = 1; --DECLARE COUNTER
Pada contoh kode 1.13, terdapat sebuah variabel @N yang berfungsi sebagai counter, yang
berfungsi sebagai penanda kondisi perulangan, apakah harus terus berjalan, atau berhenti.
Counter ini harus dipastikan pasti memenuhi kondisi kapan perulangan harus berhenti,
sehingga tidak menimbulkan infinite loop (perulangan tak terbatas). Untuk memastikan
bahwa perulangan pasti dapat berhenti atau selesai, terdapat proses incremental counter untuk
memastikan agar counter dapat memenuhi kondisi perulangan berhenti. Output dari kode 1.13
adalah sebagai berikut:
Contoh lain untuk penggunaan perulangan adalah untuk mencetak semua data nama
belakang karyawan yang tidak memiliki nilai COMMISSION_PCT (COMMISSION_PCT
bernilai NULL). Untuk menyelesaikan kebutuhan ini, terdapat penggunaan CURSOR (yang akan
dijelaskan pada Bab 2), tetapi tidak menutup kemungkinan untuk memenuhi kebutuhan hanya
dengan menggunakan perulangan tanpa CURSOR. Contoh pengkodean akan dituliskan pada
halaman berikutnya.
Pada kode 1.14 telah dibuktikan juga bahwa perulangan dapat mengandung proses percabangan
pada tiap perulangannya.
Pada kode 1.14 dan kode 1.13, counter yang digunakan memiliki tipe data angka, sedangkan
counter tidak pernah dibatasi dengan tipe data angka. Yang perlu diperhatikan adalah,
counter pasti bisa membuat perulangan berhenti. Contoh lebih lanjut tentang counter tanpa tipe
data angka akan dibahas pada materi CURSOR.
Untuk penggunaan perintah BREAK dan CONTINUE, dapat dilihat pada pengkodean di bawah
ini:
Pada kode 1.15 terdapat variabel @counter yang dipakai sebagai penanda kondisi perulangan.
Perulangan di kondisikan berhenti pada nilai @counter 10. Selama @counter bernilai kurang
dari 10, maka ada penambahan nilai +1 pada @counter. Ketika nilai @counter kurang dari 5,
program tidak melakukan apa-apa. Hal ini dikarenakan ada kondisi IF @counter < 5. Kondisi ini
berisi kata kunci CONTINUE. Ketika nilai @counter diantara 5 sampai dengan 8, maka program
melakukan pencetakan nilai @counter. Hal ini bisa dilihat pada kata kunci ELSE. Ketika nilai
@counter diatas 8, program menghentikan perulangan dengan menggunakan perintah BREAK.
Pada saat menggunakan perulangan, tidak menutup kemungkinan bahwa akan terjadi
nested loop, atau perulangan bersarang, dimana pada setiap perulangan terdapat perulangan lain
yang bekerja. Sebelum nilai counter berubah, terdapat perulangan yang harus diselesaikan lebih
dulu. Berikut adalah kebutuhan untuk mencetak pola dengan penerapan perulangan bersarang.
Seperti yang dapat dilihat pada kode 1.16, untuk setiap perulangan, terdapat perulangan lain yang
dijalankan, pada kasus ini, perulangan yang terluar (WHILE @ROW <= 10) dilakukan untuk
menentukan jumlah baris yang akan dicetak, sedangkan perulangan yang terdalam (WHILE @COL >
0) digunakan untuk membentuk pola huruf ‘A’ yang akan dicetak untuk tiap barisnya.
PRACTICE
1. Buatlah sebuah blok transact-SQL untuk menghitung dan menampilkan hasil konversi suhu
dari Celcius ke Reamur dan Fahrenheit.
Rumus konversi ke Reamur : R = (4/5)C
Rumus konversi ke Fahrenheit : F = (9/5) C + 32
Hasil program:
2. Buatlah sebuah blok transact-SQL untuk membuat dan menampilkan nim dari nomor urut 10
sampai dengan nomor urut 100. dengan syarat :
Setiap nim yang dibuat harus selisih 10 angka
Angkatan dari nim diambil dari tahun kelahiran mahasiswa dengan nama ‘Anthony’
Kode prodi dari nim adalah ‘41010’
Jumlah panjang karakter dari nim harus tepat 11 digit
Hasil program:
3. Buatlah sebuah blok transact-SQL untuk mencetak huruf ‘A’ dengan tampilan sebagai
berikut:
4. Buatlah sebuah blok transact-SQL untuk melakukan pengecekan, apakah gaji seorang
karyawan perlu mendapat kenaikan atau tidak. Untuk mengetahui apakah seorang karyawan
perlu mendapat kenaikan gaji atau tidak, harus diperiksa apakah selisih dari gaji milik
karyawan tersebut dengan rata-rata gaji pada departmentnya, melebihi 5000 atau tidak. Jika
selisih melebihi 5000, maka tampilkan pesan "need an increase", jika tidak, maka tampilkan
pesan "-". Ketika program dijalankan, data seluruh karyawan harus ditampilkan.
Contoh hasil program:
BAB 2
WORKING WITH CURSOR
Sebuah query SELECT selalu mengembalikan sekumpulan baris yang biasa disebut sebagai
resultset. Resultset dapat mengembalikan antara 0 sampai N baris, tergantung dari query SELECT yang
dijalankan. Pada pertemuan sebelumnya, query SELECT hanya digunakan untuk mengisi nilai dari tabel
ke dalam variabel, dan masing-masing query SELECT yang digunakan harus mengembalikan 1 baris data
(jumlah kolom tergantung berapa variabel yang akan diisi dengan query SELECT). Bagaimana jika
muncul kebutuhan untuk mengolah data berdasarkan query SELECT yang mengembalikan lebih
dari 1 baris? Untuk menangani kebutuhan seperti diatas, terdapat sebuah obyek pada pemrograman basis
data, yang bernama CURSOR.
Penjelasan untuk masing-masing langkah penggunaan CURSOR dapat dilihat pada halaman
berikutnya.
1. DECLARE
Pendeklarasian CURSOR dilakukan dengan menggunakan perintah DECLARE (seperti pada
saat mendeklarasikan variabel), dan menyebutkan nama dari CURSOR beserta query
SELECT yang dipakai dalam CURSOR tersebut. Perbedaan antara deklarasi CURSOR dan
variabel adalah pada saat deklarasi CURSOR, simbol “@” tidak perlu dituliskan pada
nama CURSOR, berbeda dengan deklarasi variabel. Sebagai tambahan, selain deklarasi
CURSOR, perlu dilakukan juga deklarasi variabel penampung untuk menampung kolom-
kolom hasil query SELECT pada CURSOR. Berikut adalah contoh deklarasi CURSOR
beserta deklarasi variabel penampung-nya.
--deklarasi CURSOR
DECLARE CEmp CURSOR FOR SELECT FIRST_NAME + ' ' + LAST_NAME AS FULL_NAME,
DEPARTMENT_ID, SALARY FROM EMPLOYEES WHERE SALARY BETWEEN 8000 AND 10000
Seperti pada kode 2.1, terdapat perbedaan pada saat mendeklarasikan CURSOR dan variabel.
Pada CURSOR CEmp, terdapat 3 kolom hasil query SELECT, yaitu kolom FULL_NAME
(yang merupakan kombinasi dari kolom FIRST_NAME dan LAST_NAME), kolom
DEPARTMENT_ID, dan kolom SALARY. Karena terdapat 3 kolom yang akan dihasilkan
oleh CURSOR, maka harus terdapat minimal 3 variabel yang harus dibuat/dideklarasikan
untuk memuat 3 kolom tersebut. 3 variabel yang sudah dideklarasikan adalah variabel
NAME, DEPT_ID, dan SAL.
2. OPEN
Dengan membuka CURSOR, query SELECT dalam CURSOR akan dijalankan, atau dengan
kata lain, mempopulasikan data resultset pada CURSOR, sekaligus menempatkan CURSOR
pada posisi baris pertama dari resultset. Populasi data ini disimpan secara sementara di dalam
memory (atau lebih tepatnya RAM). Untuk membuka sebuah CURSOR, digunakan perintah
OPEN. Melanjutkan dari kode 2.1, berikut adalah kode untuk membuka CURSOR CEmp.
OPEN CEmp;
3. FETCH
Setelah data dipopulasikan kedalam CURSOR, langkah selanjutnya adalah mengambil setiap
baris data menggunakan perintah FETCH NEXT. Struktur dasar penggunaan perintah
FETCH NEXT adalah sebagai berikut:
Target-list merupakan kumpulan variabel yang dipakai untuk menyimpan data masing-
masing kolom dalam cursor. Pada saat menuliskan target list, harus menyamakan antara
urutan kolom pada SELECT di CURSOR dengan urutan penulisan variabel pada
target-list. Dengan mengacu pada cursor CEmp dan variabel penampung pada kode 2.1,
berikut adalah contoh penggunaan FETCH NEXT untuk mengisi masing-masing variabel
penampung berdasarkan CURSOR CEmp.
Seperti pada kode 2.4, variabel pertama yang dituliskan adalah @NAME, diikuti dengan
@DEPT_ID, dan terakhir adalah @SAL. Urutan ini dituliskan berdasarkan query SELECT
CURSOR CEmp pada kode 2.1. Pada CURSOR CEmp, kolom pertama yang disebutkan
adalah kolom hasil operasi konkatenasi FIRST_NAME dan LAST_NAME, dan hasil kolom
ini akan dimasukkan ke variabel @NAME. Kolom kedua pada CURSOR adalah
DEPARTMENT_ID, yang akan masuk ke variabel @DEPT_ID, dan kolom terakhir adalah
kolom SALARY, yang akan masuk ke variabel @SAL.
Pada saat proses FECTH, pada umumnya, akan berkaitan dengan looping (perulangan).
Ketika proses FECTH dijalankan, maka baris pertama saja dari resultset yang akan diambil,
sedangkan untuk membaca seluruh baris dari resultset CURSOR, diperlukan penggunaan
looping untuk membaca dari baris kedua resultset hingga baris terakhir resultset CURSOR.
Kondisi yang dipakai dalam perulangan adalah memeriksa apakah setiap proses FECTH
berhasil mengambil data atau tidak, jika FETCH berhasil mengambil data, maka data yang
diambil akan diproses, lalu dilanjutkan dengan mengambil data baris berikutnya. Untuk
membantu memeriksa kondisi ini, dapat memanfaatkan sebuah variabel global (variabel yang
sudah ada pada SQL Server dan siap digunakan) yaitu @@FETCH_STATUS. Jika baris
dapat terbaca saat proses FETCH, maka @@FETCH_STATUS mengembalikan nilai 0.
Variabel @@FETCH_STATUS akan bernilai -1 jika tidak ada lagi baris yang dapat dibaca.
Berdasarkan Cursor CEmp pada kode 2.1, berikut adalah Contoh penerapan FETCH dengan
perulangan untuk membaca seluruh data pada resultset CURSOR CEmp.
DECLARE @N INT = 1;
FETCH NEXT FROM CEmp INTO @NAME, @DEPT_ID, @SAL
WHILE @@FETCH_STATUS = 0
BEGIN
print 'baris ke-' + CONVERT(VARCHAR, @N)
print 'Status Fetch :' + CONVERT(VARCHAR, @@fetch_status)
print @NAME + CHAR(9) + CONVERT(VARCHAR, @DEPT_ID) + CHAR(9) +
CONVERT(VARCHAR, @SAL)
print '======================================================'
SET @N = @N + 1
FETCH NEXT FROM CEmp INTO @NAME, @DEPT_ID, @SAL
END
Pada kode 2.5, terdapat deklarasi variabel @N bernilai awal 1, yang berfungsi untuk
menyimpan nomor baris. setelah deklarasi variabel @N terdapat proses FETCH untuk
mengambil baris pertama dari resultset CURSOR CEmp. Data yang diambil tersebut
digunakan untuk memeriksa status dari variabel @@FETCH_STATUS; jika bernilai 0, maka
baris pertama berhasil diambil, dan proses perulangan akan dimulai. Untuk tiap perulangan,
pertama-tama data yang telah diambil dengan menggunakan FETCH akan dicetak bersamaan
dengan nomor baris dan nilai @@FETCH_STATUS. Setelah selesai mencetak data, nilai
@N ditambah 1, baris berikutnya diambil dengan perintah FETCH yang sama dengan
perintah FETCH sebelum perulangan dimulai. Dengan kata lain, selama nilai
@@FETCH_STATUS adalah 0 atau dengan kata lain, selama pengambilan baris data
berhasil, maka looping akan tetap berjalan.
4. CLOSE
Setelah seluruh data selesai dibaca, sangat penting untuk membersihkan CURSOR. Untuk
melakukan ini, dibutuhkan dua kata kunci yaitu CLOSE untuk menutup CURSOR dan
DEALLOCATE untuk menghapus memory yang digunakan oleh CURSOR. Jika perintah
CLOSE dan DEALLOCATE tidak dijalankan setelah menjalankan deklarasi atau FETCH
pada CURSOR, maka CURSOR yang sama tidak akan bisa dideklarasikan/dijalankan ulang.
Melanjutkan contoh yang sudah digunakan sebelumnya, berikut adalah contoh penggunaan
perintah CLOSE dan DEALLOCATE untuk menutup CURSOR CEmp.
CLOSE CEmp;
DEALLOCATE CEmp;
4 langkah di atas adalah sebuah kesatuan yang lengkap, jika salah satu langkah tidak ada,
maka besar kemungkinan akan muncul error atau ketidaksamaan antara kebutuhan
dengan hasil CURSOR. Secara lengkap, proses penggunaan CURSOR pada kode 2.1 dapat
dilihat pada contoh koding di halaman berikutnya, sedangkan untuk output dari CURSOR dapat
dilihat pada gambar 2.2.
--deklarasi CURSOR
DECLARE CEmp CURSOR FOR SELECT FIRST_NAME + ' ' + LAST_NAME AS FULL_NAME,
DEPARTMENT_ID, SALARY FROM EMPLOYEES WHERE SALARY BETWEEN 8000 AND 10000
--membuka CEmp
OPEN CEmp;
DECLARE @N INT = 1;
FETCH NEXT FROM CEmp INTO @NAME, @DEPT_ID, @SAL
WHILE @@FETCH_STATUS = 0
BEGIN
print 'baris ke-' + CONVERT(VARCHAR, @N)
print 'Status Fetch :' + CONVERT(VARCHAR, @@fetch_status)
print @NAME + CHAR(9) + CONVERT(VARCHAR, @DEPT_ID) + CHAR(9) +
CONVERT(VARCHAR, @SAL)
print '======================================================'
SET @N = @N + 1
FETCH NEXT FROM CEmp INTO @NAME, @DEPT_ID, @SAL
END
CLOSE CEmp;
DEALLOCATE CEmp;
NESTED CURSOR
Karena CURSOR menggunakan perulangan, maka tidak menutup kemungkinan bahwa
CURSOR juga dapat menerapkan CURSOR bersarang (nested CURSOR). Nested CURSOR
digunakan untuk memproses data dalam struktur yang lebih kompleks. Sama seperti pada saat
melakukan perulangan, logika berpikir nested CURSOR adalah CURSOR yang berjalan di
dalam CURSOR lain (perulangan yang berjalan di dalam perulangan lain).
Salah satu implementasi nested CURSOR adalah untuk memproses data yang dapat
dikelompokkan, contohnya, memenuhi kebutuhan untuk menampilkan daftar karyawan dari
setiap bagian/department, lengkap dengan gaji dari karyawan tersebut. Untuk memenuhi
kebutuhan tersebut, pertama-tama terdapat CURSOR yang digunakan untuk mencetak semua
DEPARTMENT_ID dan DEPARTMENT_NAME. Setelah berhasil menjalankan CURSOR
yang pertama, maka untuk setiap pemrosesan baris data pada CURSOR pertama, terdapat
CURSOR lain yang berjalan untuk mencetak EMPLOYEE_ID, nama lengkap karyawan, dan
SALARY dari seluruh karyawan pada DEPARTMENT_ID yang sudah diambil pada CURSOR
Program Studi S1 Sistem Informasi 26
August 6, 2018 [MODUL PRAKTIKUM PEMROGRAMAN BASIS DATA]
pertama. CURSOR kedua ini harus berjalan sampai selesai sebelum CURSOR pertama
membaca baris data berikutnya (FETCH NEXT). Contoh output yang diharapkan adalah
sebagai berikut:
ini proses DECLARE hingga CLOSE harus dibuat. Berikut adalah coding untuk membuat
CURSOR yang pertama.
--DECLARE
DECLARE CDEPT CURSOR FOR SELECT DEPARTMENT_ID, DEPARTMENT_NAME FROM DEPARTMENTS
DECLARE @DEPT_ID NUMERIC(3), @DEPT_NAME VARCHAR(30)
--OPEN
OPEN CDEPT
--FETCH
FETCH NEXT FROM CDEPT INTO @DEPT_ID, @DEPT_NAME
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'DEPARTMENT ID: ' + CONVERT(VARCHAR, @DEPT_ID)
PRINT 'DEPARTMENT NAME: ' + @DEPT_NAME
Pada saat kode 2.8 dijalankan, akan menghasilkan tampilan (sebagian) sebagai berikut:
2. Setelah CURSOR pertama berhasil dibuat, maka CURSOR kedua akan mulai dibuat di
dalam CURSOR pertama. Sebagai catatan dan seperti yang dituliskan sebelumnya,
CURSOR kedua harus berjalan sampai selesai sebelum CURSOR pertama membaca
baris data berikutnya (FETCH NEXT), sehingga posisi penulisan CURSOR kedua
Program Studi S1 Sistem Informasi 28
August 6, 2018 [MODUL PRAKTIKUM PEMROGRAMAN BASIS DATA]
diletakkan setelah pemrosesan baris pada CURSOR pertama, tetapi sebelum CURSOR
pertama melakukan FETCH NEXT. Posisi penulisan CURSOR kedua akan ditunjukkan
pada kode 2.9.
--DECLARE
DECLARE CDEPT CURSOR FOR SELECT DEPARTMENT_ID, DEPARTMENT_NAME FROM DEPARTMENTS
DECLARE @DEPT_ID NUMERIC(3), @DEPT_NAME VARCHAR(30)
--OPEN
OPEN CDEPT
--FETCH
FETCH NEXT FROM CDEPT INTO @DEPT_ID, @DEPT_NAME
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'DEPARTMENT ID: ' + CONVERT(VARCHAR, @DEPT_ID)
PRINT 'DEPARTMENT NAME: ' + @DEPT_NAME
END
--CLOSE
CLOSE CDEPT
DEALLOCATE CDEPT Kode 2.9 Posisi CURSOR kedua akan dituliskan
3. Pada CURSOR kedua, query SELECT yang digunakan adalah query SELECT untuk
mengambil EMPLOYEE_ID, nama lengkap (kombinasi FIRST_NAME dan LAST_NAME),
dan SALARY berdasarkan DEPARTMENT_ID yang sudah diambil pada CURSOR yang
pertama (DEPARTMENT_ID yang dimasukkan ke variabel @DEPT_ID). Kenapa
berdasarkan @DEPT_ID? Karena CURSOR pertama sudah mengambil semua data
department, sehingga pada CURSOR kedua, cukup mencari karyawan pada tiap-tiap
department saja. Karena @DEPT_ID sudah diisi melalui proses FETCH NEXT dan belum
berganti ke baris berikutnya (lihat posisi penulisan CURSOR kedua pada kode 2.9), maka
nilai yang masih tersimpan pada @DEPT_ID bisa digunakan sebagai kondisi pada CURSOR
kedua. Tentu saja, pada CURSOR kedua inipun, proses DECLARE hingga CLOSE juga
harus dituliskan secara lengkap, sebelum CURSOR pertama melakukan FETCH
NEXT ke baris berikutnya.
Pengkodean CURSOR kedua dapat anda lihat pada kode 2.10 di halaman berikutnya,
sedangkan sebagian hasil dari CURSOR kedua dapat dilihat pada gambar 2.3.
--DECLARE CURSOR 1
DECLARE CDEPT CURSOR FOR SELECT DEPARTMENT_ID, DEPARTMENT_NAME FROM DEPARTMENTS
DECLARE @DEPT_ID NUMERIC(3), @DEPT_NAME VARCHAR(30)
--DECLARE CURSOR 2
DECLARE CEMP CURSOR FOR SELECT EMPLOYEE_ID, FIRST_NAME + ' ' + LAST_NAME FULL_NAME,
SALARY FROM EMPLOYEES WHERE DEPARTMENT_ID = @DEPT_ID
FETCH NEXT FROM CEMP INTO @EMP_ID, @FNAME, @SAL --FETCH CURSOR 2
IF @@FETCH_STATUS <> 0
BEGIN
PRINT 'NO EMPLOYEE'
PRINT '============================================='
PRINT ' '
END
ELSE
BEGIN
PRINT 'LIST OF EMPLOYEE(S):'
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT CONVERT(VARCHAR, @EMP_ID) + CHAR(9) + @FNAME + CHAR(9) +
CONVERT(VARCHAR,@SAL)
FETCH NEXT FROM CEMP INTO @EMP_ID, @FNAME, @SAL
END
DECLARE @JML INT
SELECT @JML = COUNT(EMPLOYEE_ID) FROM EMPLOYEES WHERE DEPARTMENT_ID =
@DEPT_ID
PRINT 'NUMBER OF EMPLOYEE(S) IN DEPARTMENT: ' + CONVERT(VARCHAR, @JML)
PRINT '============================================='
PRINT ' '
END
Seperti yang sudah dituliskan sebelumnya, query SELECT pada CURSOR kedua hanya akan
melakukan pengambilan data berdasarkan DEPARTMENT_ID (dengan memanfaatkan
variabel @DEPT_ID yang sudah diisi pada CURSOR pertama). Setiap kali CURSOR
pertama mengambil baris berikutnya, secara otomatis, nilai pada variabel @DEPT_ID pasti
akan ikut berubah, sehingga DEPARTMENT_ID yang digunakan pada CURSOR kedua juga
pasti akan berbeda-beda. Selain itu, pada kode 2.10 terdapat percabangan dengan kondisi
@@FETCH_STATUS bukan 0, yang berfungsi untuk memeriksa apakah FETCH pertama
pada CURSOR kedua berhasil mengambil data atau tidak. Jika tidak berhasil mengambil
data, maka proses looping untuk mengambil semua data tidak akan dilakukan,
digantikan dengan proses mencetak pesan “NO EMPLOYEE”, sedangkan jika FETCH
pertama dari CURSOR kedua berhasil mengambil data, maka proses looping untuk
menampilkan data seluruh karyawan pada department akan dijalankan, sekaligus dengan
query untuk mengambil jumlah karyawan pada department. Perbedaan kondisi
@@FETCH_STATUS sudah terlihat pada gambar 2.3.
Catatan lain terkait kode 2.10 adalah proses CLOSE dari CURSOR kedua dijalankan
sebelum FETCH NEXT dari CURSOR pertama. Hal ini untuk membuktikan dan memastikan
bahwa CURSOR kedua harus selesai sebelum CURSOR pertama mengambil baris
berikutnya (FETCH NEXT).
PRACTICE
1. Buatlah sebuah blok transact-SQL untuk mengambil dan menampilkan data mahasiswa (nim,
nama, dan alamat mahasiswa) berdasarkan kota tinggal dari mahasiswa (kota tinggal
dipilih/diisi melalui variabel). Setelah menampilkan data mahasiswa, tampilkan juga jumlah
mahasiswa pada kota tersebut.
Hasil program:
2. Buatlah sebuah blok transact-SQL untuk Tampilkan data mahasiswa (nim, nama, rata-rata
nilai akhir, dan status) untuk dikelompokkan berdasarkan program studi dan ditampilkan
untuk tiap-tiap prodi. status berisi "baik" jika rata-rata nilai akhir dari mahasiswa di atas nilai
rata-rata seluruh mahasiswa pada program studi tersebut, jika tidak, maka status berisi
"Kurang" nilai akhir diambil dengan rumus (25%tugas) + (20%UTS) + (60%UAS)
Contoh hasil program:
BAB 3
FUNCTIONS
Penjelasan komponen dari kode untuk membuat function, seperti terlihat pada kode 3.1 adalah
sebagai berikut.
<function_name>
Bagian ini berisi nama dari function. Sama seperti pada saat menuliskan nama tabel di
CREATE TABLE, pada saat menuliskan nama dari function, nama tersebut tidak boleh
diawali angka dan tidak boleh kembar dengan nama fungsi lain yang sudah ada pada
database.
([parameter, parameter, . . .])
Bagian ini berisi parameter dari function dan bersifat optional. Parameter bisa digambarkan
sebagai wadah untuk nilai yang akan dimasukkan ke dalam function. Nilai yang sudah masuk
ke dalam parameter dapat digunakan pada pemrosesan di dalam function. Sebuah function
dapat menggunakan lebih dari 1 (satu) parameter, tergantung dari berapa banyak nilai yang
harus diterima oleh function sebelum pemrosesan pada function dapat berjalan. Seperti pada
saat mendeklarasikan variabel, pada saat menyebutkan parameter, tipe data dari parameter
harus disebutkan, TANPA jumlah karakter/digit (length). Jika sebuah function tidak
membutuhkan parameter, maka bagian ini diganti dengan “()” (kurung kosong). Selain nama
dari parameter dan tipe data, penulisan parameter dapat juga menuliskan nilai awal (default
value) dari parameter tersebut. Nilai awal pada parameter akan digunakan JIKA parameter
TIDAK DIISI pada saat function digunakan.
RETURNS < [data type]/[TABLE] >
Bagian ini berisi definisi tipe data dari nilai yang akan dikembalikan (return value) dari
function yang akan dibuat. Kata kunci RETURNS harus dituliskan, sedangkan data type atau
TABLE harus dipilih salah satu. Jika sebuah function akan mengembalikan scalar-value,
maka bagian ini harus berisi tipe data dari nilai yang akan dikembalikan (VARCHAR,
NUMERIC, FLOAT, dll) dan jumlah karakter/digit (length), sedangkan jika function akan
mengembalikan nilai berupa tabel, maka gunakan kata kunci TABLE.
<process code>
Bagian ini berisi proses yang digambarkan dengan pengkodean atau dengan kata lain, bagian
ini berisi konten dari function. Proses atau pengkodean yang dituliskan pada bagian ini harus
menghasilkan sebuah nilai (1 nilai) yang akan dikembalikan dengan perintah RETURN.
RETURN [return_value]/ [SELECT command]
Bagian ini merupakan perintah yang akan mengeluarkan nilai/hasil dari proses pada function.
Perintah RETURN harus digunakan, sedangkan return_value dapat digantikan dengan
variabel yang mengandung nilai yang akan dikembalikan, atau nilai itu sendiri (tanpa
menggunakan variabel). Jika function yang dibuat adalah table-valued function, maka setelah
perintah RETURN, perintah SELECT ditulis untuk menggantikan return_value. Penulisan
RETURN pada bagian ini BERBEDA dengan penulisan RETURNS pada saat
mendefinisikan tipe data dari nilai yang akan dikembalikan. Perbedaan terletak pada huruf “S”
pada akhir perintah RETURN.
Setelah sebuah function sudah selesai dibuat, function tersebut masih dapat dimanipulasi,
atau dirubah konten di dalamnya. Untuk mengubah konten di dalam function, digunakan perintah
ALTER. Struktur dasar pengkodean untuk mengubah konten dari function adalah sebagai berikut.
Kode 3.2 Struktur dasar pengkodean untuk mengubah function yang sudah ada
Seperti pada kode 3.2, struktur dasar perubahan konten function sangat mirip dengan pada saat
membuat function pertama kali, hanya merubah perintah CREATE dengan perintah ALTER.
Terdapat beberapa limitasi pada saat merubah konten dari function yang sudah jadi:
Nama dari function yang sudah jadi, tidak dapat dirubah.
Scalar-valued function tidak dapat dirubah menjadi table-valued function
Jika sebuah function sudah tidak digunakan lagi, maka function tersebut dapat dihapus
dengan menggunakan perintah DROP. Struktur dasar pengkodean untuk menghapus function
yang sudah ada adalah sebagai berikut:
Kode 3.3 Struktur dasar pengkodean untuk menghapus function yang sudah ada
SCALAR-VALUED FUNCTION
Seperti yang telah dijelaskan sebelumnya, scalar-valued function adalah tipe function yang
mengembalikan 1 (satu) nilai dengan tipe data tertentu. Tipe data yang digunakan pada scalar-
valued function adalah tipe data yang sama dengan tipe data pada saat pembuatan tabel pada
database. Berikut adalah beberapa contoh pembuatan dan penggunaan scalar-valued function.
Contoh pertama adalah penggunaan function untuk menentukan grade nilai dari seorang
mahasiswa pada matakuliah, berdasarkan nilai akhir dari mahasiswa tersebut. berikut adalah
pengkodean pembuatan function untuk menyelesaikan kebutuhan tersebut.
Seperti yang telah dijelaskan sebelumnya, sebuah function tidak dapat digunakan sendirian,
tetapi harus diikutsertakan pada aplikasi atau perintah SELECT yang lain. berikut adalah contoh
penggunaan function GRADE_NILAI.
Program Studi S1 Sistem Informasi 39
August 6, 2018 [MODUL PRAKTIKUM PEMROGRAMAN BASIS DATA]
pada kode 3.5, function GRADE_NILAI ini akan memproses nilai angka 100 yang
dimasukkan ke dalam function melalui parameter @PNA. Lalu hasil dari function tersebut
akan ditampilkan pada tab result dengan nama kolom “GRADE_NILAI_MHS”, karena
terdapat penggunaan column alias “GRADE_NILAI_MHS”. Hasil dari eksekusi perintah di
atas adalah sebagai berikut.
Berikut adalah contoh lain penggunaan function GRADE_NILAI pada perintah SELECT
yang lebih kompleks.
Pada kode 3.6 terdapat kebutuhan untuk menampilkan nilai akhir dan grade nilai dari
mahasiswa yang sudah menempuh matakuliah dengan kode “S_016”. Perbedaan dengan
contoh pada kode 3.5 adalah pada kode 3.6, parameter @PNA dari fungsi diisi dengan hasil
Pada kode 3.7 terdapat sebuah variabel dengan nama @GRADE_NA yang dideklarasikan
dengan tipe data VARCHAR. Setelah deklarasi, variabel diisi dengan menggunakan
function GRADE_NILAI, dengan nilai @PNA 70. Setelah proses pengisian nilai variabel,
variabel @GRADE_NA dicetak dengan format seperti pada pengkodean di atas. Hasil dari
kode 3.7 adalah sebagai berikut.
Untuk contoh yang lebih kompleks, sebuah function dapat digunakan juga CURSOR.
Berikut adalah contoh penggunaan function (user-defined function) pada CURSOR.
Pada kode 3.8, function GRADE_NILAI digunakan pada setiap perulangan CURSOR untuk
menentukan grade dari nilai akhir tertinggi milik setiap matakuliah. Sebagian dari hasil
kode 3.8 adalah sebagai berikut.
Contoh lain penggunaan function adalah untuk membuat NIM dari mahasiswa secara otomatis.
Berikut adalah contoh pengkodean function yang dapat digunakan untuk membuat NIM
mahasiswa.
Function yang ditunjukkan pada kode 3.9 adalah contoh function yang tidak memiliki
parameter. Function GEN_NIM pada kode 3.9 adalah function yang dapat menghasilkan NIM
terbaru bagi mahasiswa pada program studi dengan kode “41010”. urutan proses dari function
adalah sebagai berikut:
1. Deklarasi variabel @PRODI untuk menyimpan kode prodi, @NIM untuk menyimpan NIM
yang sudah jadi, @ANG untuk menyimpan angkatan mahasiswa, dan @NEW untuk
menyimpan nomor urut untuk NIM yang baru. Variabel @PRODI telah diberi nilai awal
“41010”.
2. Variabel @ANG diisi dengan 2 digit paling kanan dari tahun hari ini.
(RIGHT(YEAR(GETDATE()),2))
3. Variabel @NEW diisi dengan jumlah mahasiswa + 1 (COUNT(NIM) + 1) dari mahasiswa
yang memiliki kode angkatan dan program studi yang sama dengan variabel @ANG dan
@PRODI. (WHERE NIM LIKE @ANG + @PRODI + '%').
4. Setelah angkatan (@ANG), program studi (@PRODI), dan nomor urut (@NEW) sudah
didapatkan, semua variabel tersebut digabungkan (concate) agar menjadi satu nilai dan
disimpan pada variabel @NIM.
(SET @NIM = @ANG + @PRODI + RIGHT ('0000'+CONVERT(VARCHAR, @NEW),4))
Pada proses penggabungan, terdapat penggunaan fungsi RIGHT dengan jumlah karakter 4.
Fungsi ini digunakan untuk memastikan agar setelah ada penambahan 4 digit angka 0
(“0000”) sebelum nomor urut (@NEW), nilai yang digabungkan pada variabel @NIM tetap
4 digit.
Karena function GEN_NIM tidak memiliki parameter, pada saat digunakan, setelah nama
function tambahkan simbol “()”. Contoh:
Hasil dari kode 3.10 adalah sebagai berikut. Sedikit penjelasan, pada data yang digunakan untuk
pembuatan modul ini, tidak ada NIM yang memenuhi kondisi dari angkatan dan kode prodi,
sehingga nomor urut NIM dimulai dari nomor 1.
Pada contoh-contoh yang telah ditunjukkan sebelumnya, terdapat persamaan pada saat
menggunakan function, yaitu terdapat tulisan “DBO.” Sebelum nama dari function. “DBO” yang
dituliskan di awal nama function ini adalah nama schema, tempat function dibuat. Sebuah
function terletak pada schema di dalam database, dan 1 database bisa memiliki banyak schema.
Pada saat menggunakan function, nama dari schema HARUS DISEBUTKAN sebelum nama
function. Nama dari schema tempat function disimpan akan selalu tampil di depan nama function.
TABLE-VALUED FUNCTION
Berbeda dengan scalar-valued function, table-valued function dapat menghasilkan lebih
dari satu nilai, karena sesuai dengan jenis nilai yang dihasilkan, table-valued function
mengembalikan nilai dalam bentuk tabel. Table-valued function dapat digunakan sebagai
pengganti sebuah tabel pada perintah SQL.
Berikut adalah contoh penerapan table-valued function untuk mengambil data peserta
matakuliah berdasarkan range nilai akhir dan kode matakuliah.
tabel pada perintah SQL, dan hasil dari function PESERTA_MATKUL dan tabel
MAHASISWA sama-sama memiliki kolom NIM, sehingga memungkinkan untuk
digabungkan dengan JOIN.
Scalar-valued function (GRADE_NILAI) dapat digunakan bersamaan dengan table-valued
function pada satu perintah SQL atau blok T-SQL yang sama
Berikut adalah hasil dari kode 3.13.
Table-valued function sangat cocok digunakan untuk menggantikan query SELECT yang rutin
digunakan atau diakses, sehingga dapat mempersingkat query SELECT tanpa menghilangkan
identitas sebagai tabel.
Setelah membuat function yang pertama, berikutnya adalah membuat table-valued function
EMP_MGR, yang sekaligus akan memanggil function FULL_NAME di dalamnya. Function ini
akan berfungsi mengambil data nama lengkap seluruh karyawan beserta nama lengkap manager
dari masing-masing karyawan.
Pada kode 3.15 dapat dilihat bahwa function FULL_NAME digunakan 2 kali, pertama untuk
mencari nama lengkap dari karyawan (DBO.FULL_NAME(EMPLOYEE_ID)), sedangkan yang
kedua digunakan untuk mencari nama dari manager (DBO.FULL_NAME(MANAGER_ID)).
Telah diketahui bahwa kolom MANAGER_ID adalah kolom yang mereferensi kolom
EMPLOYEE_ID, sehingga isi dari kolom MANAGER_ID pasti terdapat juga pada kolom
EMPLOYEE_ID. Hal ini memungkinkan nilai pada kolom MANAGER_ID untuk dimasukkan
juga ke function FULL_NAME, karena function FULL_NAME digunakan untuk mencari nama
lengkap BERDASARKAN EMPLOYEE_ID. Berikut adalah pengkodean sederhana yang dapat
digunakan untuk menjalankan function EMP_MGR.
Mengingatkan lagi pada kode 3.16, karena function EMP_MGR tidak memiliki parameter, tidak
ada nilai yang dimasukkan ke dalam function (kurung kosong).
Sebagian dari hasil kode 3.16 adalah sebagai berikut:
PRACTICE
1. Buatlah sebuah Function yang berfungsi untuk melakukan penghitungan gaji tahunan dari
setiap karyawan. Rumus penghitungan untuk gaji tahunan adalah sebagai berikut:
𝑎𝑛𝑛𝑢𝑎𝑙 𝑠𝑎𝑙𝑎𝑟𝑦 = (𝑠𝑎𝑙𝑎𝑟𝑦 × 12) + (𝑐𝑜𝑚𝑚𝑖𝑠𝑠𝑖𝑜𝑛𝑝𝑐𝑡 × 𝑠𝑎𝑙𝑎𝑟𝑦 × 12)
Function ini memiliki sebuah parameter untuk menerima id karyawan (EMPLOYEE_ID).
Untuk membuktikan keberhasilan fungsi, buatlah sebuah perintah SQL untuk menampilkan
data sebagai berikut:
2. Buatlah sebuah Function untuk memeriksa apakah EMPLOYEE_ID yang sudah dimasukkan
melalui parameter, benar-benar ada pada tabel employees. Function ini mengembalikan nilai
bertipe BOOLEAN. Jika EMPLOYEE_ID benar-benar ada, maka function harus
mengembalikan nilai TRUE, jika tidak, kembalikan nilai FALSE. Buatlah juga blok transact-
SQL untuk membuktikan bahwa Function sudah berjalan. Catatan: TIDAK ADA TIPE
DATA BOOLEAN PADA SQL SERVER
3. Buatlah sebuah function untuk mengambil nama jabatan dari karyawan berdasarkan job_ID.
Beri nama function tersebut sebagai function GET_JOB_TITLE, lalu gabungkan/masukkan
function tersebut pada function EMP_MGR pada halaman 48 agar dapat mengeluarkan output
seperti berikut pada saat dijalankan.
4. Ubahlah function EMP_MGR yang telah dibuat pada halaman 48 agar dapat menampilkan
data berdasarkan department (untuk sementara, function EMP_MGR menampilkan data
seluruh karyawan tanpa disaring berdasarkan department).
BAB 4
PROCEDURE
Seperti yang sudah dituliskan pada bab sebelumnya, obyek dalam T-SQL dibangun untuk
memenuhi kebutuhan terhadap kemudahan pemeliharaan, penyimpanan script, dan penggunaan
kembali. Secara sederhana, jika terdapat sebuah kumpulan perintah atau pengkodean blok T-
SQL (BEGIN…END) yang harus dijalankan secara rutin atau berulang-ulang, lebih dari satu kali,
maka sangat disarankan agar blok T-SQL tersebut dirubah menjadi obyek T-SQL untuk
memudahkan dalam penggunaan atau eksekusi dan mengurangi kebutuhan untuk mengetikkan
ulang blok T-SQL.
Obyek T-SQL yang akan dibahas berikutnya adalah obyek stored procedure (berikutnya
akan disebut procedure). Sama seperti function yang sudah dibahas sebelumnya, procedure
adalah sebuah obyek T-SQL atau Common Runtime Language (CLR) yang dapat menerima
parameter, melakukan proses seperti penghitungan yang kompleks atau pemrosesan data dari
tabel. Berbeda dengan function, sebuah procedure umumnya tidak menghasilkan/mengembalikan
sebuah nilai, tetap masih dapat mengembalikan nilai dengan menggunakan parameter bertipe
OUT. Selain tidak menghasilkan nilai, sebuah procedure tidak dapat digabungkan dengan
perintah SELECT, karena procedure membutuhkan keyword EXECUTE sebagai perintah untuk
menjalankan procedure tersebut, atau procedure dijalankan dengan memanggil nama dari
procedure itu sendiri. Karena adanya limitasi ini, sebuah procedure umumnya dijalankan pada
blok T-SQL, di dalam procedure lain, atau dijalankan berdiri sendiri.
Seperti pada saat membuat sebuah function (user-defined function), sebuah procedure
dibuat dengan menggunakan perintah CREATE, karena setelah dibuat, procedure akan
tersimpan di dalam database. Setelah sebuah procedure dibuat, konten atau proses dari
procedure tersebut masih dapat dirubah dengan perintah ALTER; atau procedure tersebut dapat
dihapus dengan perintah DROP.
Berdasarkan kode 4.1, dapat dilihat bahwa struktur pengkodean untuk pembuatan procedure
lebih sederhana dari pada pembuatan function. Penjelasan struktur pada kode 4.1 adalah sebagai
berikut:
<procedure_name>
Bagian ini berisi nama dari procedure yang akan dibuat. Sama seperti pada saat menuliskan
nama tabel di CREATE TABLE atau nama function pada CREATE FUNCTION, pada saat
menuliskan nama dari procedure, nama tersebut tidak boleh diawali angka dan tidak boleh
kembar dengan nama procedure lain yang sudah ada pada database.
[([parameter, parameter, . . .])]
Bagian ini berisi parameter dari procedure dan bersifat optional. Parameter bisa
digambarkan sebagai wadah untuk nilai yang akan dimasukkan ke dalam procedure. Nilai
yang sudah masuk ke dalam parameter dapat digunakan pada pemrosesan di dalam
procedure. Sebuah procedure dapat menggunakan lebih dari 1 (satu) parameter, tergantung
dari berapa banyak nilai yang dibutuhkan oleh procedure sebelum pemrosesan pada
procedure dapat berjalan. Seperti pada function, parameter dari sebuah procedure harus
dituliskan dengan simbol “@” sebelum nama, dan dilengkapi dengan tipe data DAN
panjang(length). Jika sebuah procedure tidak membutuhkan parameter, maka bagian ini
tidak perlu dituliskan (tanda “()” juga TIDAK PERLU digunakan). Selain nama dari
parameter dan tipe data, penulisan parameter dapat juga menuliskan nilai awal (default
value) dari parameter tersebut. Nilai awal pada parameter akan digunakan JIKA parameter
TIDAK DIISI pada saat procedure digunakan. Pada saat mengisi parameter, baik function
maupun procedure, HARUS MEMPERHATIKAN urutan pengisian nilai ke dalam
parameter (nilai pertama akan masuk ke parameter pertama, nilai kedua akan masuk ke
parameter kedua, dst,). Sesuai dengan kode 4.1, penulisan parameter dipisahkan dengan
simbol koma (“,”) antara parameter satu dengan yang lain.
<process code>
Bagian ini berisi proses yang digambarkan dengan pengkodean atau dengan kata lain, bagian
ini berisi konten dari procedure. Proses atau pengkodean yang dituliskan pada bagian ini
tidak mengandung kata kunci RETURN, sehingga tidak harus menghasilkan nilai apapun.
Setelah sebuah procedure sudah selesai dibuat, procedura tersebut masih dapat
dimanipulasi, atau dirubah konten prosesnya. Untuk mengubah konten di dalam procedure,
digunakan perintah ALTER. Struktur dasar pengkodean untuk mengubah konten dari procedure
adalah sebagai berikut.
Kode 4.2 Struktur dasar pengkodean untuk mengubah procedure yang sudah ada
Seperti pada kode 4.2 dan kode 3.2 (mengubah function), untuk mengubah procedure yang sudah
ada, cukup merubah perintah CREATE dengan perintah ALTER. Terdapat beberapa limitasi
pada saat merubah konten dari function yang sudah jadi, tetapi tidak akan dibahas pada
praktikum ini. Limitasi dapat dibaca pada tautan berikut: https://docs.microsoft.com/en-us/sql/t-
sql/statements/alter-procedure-transact-sql?view=sql-server-2017.
Jika sebuah procedure sudah tidak digunakan lagi, maka procedure tersebut dapat dihapus
dengan menggunakan perintah DROP. Struktur pengkodean untuk menghapus procedure adalah
sebagai berikut.
belakang), program studi, dan umur mahasiswa per tahun 2015. Pengkodean pembuatan
procedure untuk memenuhi kebutuhan tersebut adalah sebagai berikut.
Setelah sebuah procedure berhasil dibuat, maka procedure tersebut dapat digunakan dan
tersimpan pada database tempat procedure tersebut dibuat. Untuk menemukan procedure yang
telah dibuat, dapat ditemukan pada <database name> Programmability Stored
Procedures.
Setelah sebuah procedure berhasil dibuat, maka procedure tersebut sudah dapat digunakan.
Pada penjelasan sebelumnya, perintah EXECUTE dibutuhkan untuk menggunakan sebuah
procedure, tetapi secara lengkap, terdapat 3 (tiga) macam cara untuk menggunakan atau
menjalankan sebuah procedure.
--CARA 1
EXECUTE PROCDATAMHS '06'
--CARA 2
EXEC PROCDATAMHS '07'
--CARA 3
PROCDATAMHS '08'
Selain contoh cara penggunaan procedure, pada kode 4.5 juga dapat dilihat cara pengisian nilai
parameter dari procedure. Berbeda dengan pengisian parameter pada function, meskipun pada
saat procedure dibuat, terdapat penggunaan tanda kurung (“()”) untuk mengawali dan
mengakhiri penulisan parameter, pada saat parameter tersebut diisi, tanda kurung (“()”) tidak
digunakan sama sekali, cukup memberi spasi antara nama procedure dengan nilai dari parameter
pertama. Jika parameter lebih dari 1 (satu), maka pisahkan nilai untuk tiap-tiap parameter
dengan menggunakan simbol koma (“,”). Hasil penggunaan procedure dengan menggunakan
cara 2 dari kode 4.5 dapat dilihat pada halaman berikutnya.
Selain digunakan untuk menampilkan data seperti contoh pertama, umumnya procedure
digunakan untuk melakukan pemrosesan yang sama sekali tidak mengembalikan/menghasilkan
sebuah nilai, seperti melakukan manipulasi dari data. Sebagai contoh kedua, sebuah procedure
akan dibuat untuk memenuhi kebutuhan memasukkan data program studi baru ke dalam
database. pengkodean dari procedure untuk memenuhi kebutuhan tersebut adalah sebagai
berikut.
Pada gambar 4.3, terdapat pengisian lebih dari 1 (satu) parameter. Seperti yang sudah
ditunjukkan sebelumnya, pengisian lebih dari 1 (satu) parameter dipisahkan dengan simbol
koma (“,”) dan HARUS memperhatikan urutan pengisian parameter. Pada gambar 4.3 dan
mengacu juga pada kode 4.6, nilai “42520” akan masuk ke parameter @PKD_PRODI, “D4
Robotika” akan masuk ke parameter @PNM_PRODI, dan nilai 4 (empat) akan masuk ke
parameter @PMASA. Jika procedure sudah berjalan dan pada procedure tersebut tidak ada
perintah untuk menampilkan data, maka umumnya akan tampil keterangan berapa banyak baris
data yang terpengaruh dari proses pada procedure (contoh : 1 row(s) affected).
Untuk membuktikan apakah data program studi yang baru telah benar-benar tersimpan,
sebuah perintah SELECT digunakan untuk mencari data yang telah dimasukkan pada gambar 4.3.
Gambar 4.4 Pembuktian data program studi berhasil tersimpan via procedure
Sebagai catatan, sebuah CURSOR juga dapat digunakan di dalam procedure, karena
sebuah procedure, pada umumnya, tidak menghasilkan nilai apapun. Contoh penggunaan
CURSOR pada procedure tidak ditunjukkan pada bab ini.
OUT PARAMETER
Seperti yang telah dijelaskan sebelumnya, sebuah procedure pada umumnya tidak
menghasilkan sebuah nilai, tetapi jika sebuah procedure “diharuskan” untuk mengembalikan
atau menghasilkan sebuah nilai, maka procedure tersebut dapat menggunakan parameter bertipe
OUT untuk mengembalikan atau menghasilkan nilai dari dalam procedure.
Penulisan parameter bertipe OUT sama dengan penulisan parameter pada umumnya, tetapi
ditambah dengan keyword OUT atau OUTPUT setelah menuliskan tipe data dan length dari
parameter. Sebagai contoh penggunaan OUT parameter, procedure NEW_PRODI yang telah
dibuat pada kode 4.6 akan dirubah prosesnya, dan ditambahi dengan proses pemeriksaan apakah
data yang dimasukkan ke dalam basis data melalui procedure telah berhasil masuk atau gagal.
Perubahan pengkodean dari procedure NEW_PRODI adalah sebagai berikut.
IF @@ROWCOUNT = 1
BEGIN
SET @PSUCCESS = 1
END
ELSE IF @@ROWCOUNT = 0
BEGIN
SET @PSUCCESS = 0
END
END
berhasil disimpan), jika @@ROWCOUNT bernilai 0, maka data tidak berhasil disimpan,
sehingga nilai 0 dimasukkan ke parameter @PSUCCESS (status data gagal disimpan).
Untuk menggunakan procedure yang memiliki OUT parameter, perlu disiapkan sebuah
variabel untuk menampung nilai yang akan dikeluarkan oleh OUT parameter. Contoh
penggunaan paling sederhana dari procedure dengan OUT parameter adalah sebagai berikut.
IF @CEK = 1
BEGIN
PRINT 'DATA BERHASIL DISIMPAN'
END
Pada kode 4.8, terdapat variabel @CEK yang digunakan untuk menerima nilai yang akan
dikeluarkan oleh parameter OUT. Variabel @CEK dituliskan pada urutan yang sama dengan
urutan posisi dari parameter @PSUCCESS dari procedure NEW_PRODI (lihat kode 4.7 dan
penjelasannya). Pada saat menuliskan variabel @CEK pada posisi parameter di procedure (lihat
baris ke 2 kode 4.8), JANGAN LUPA menuliskan keyword OUT untuk memperjelas bahwa
variabel @CEK diletakkan pada posisi OUT parameter. Ketika blok T-SQL pada kode 4.8
dijalankan, akan keluar hasil sebagai berikut.
Variabel @CEK bernilai 1 karena procedure sudah berhasil memasukkan data program studi,
sehingga pesan “DATA BERHASIL DISIMPAN” akan dicetak. Disini sekaligus membuktikan
bahwa dengan menggunakan parameter bertipe OUT, maka sebuah procedure dapat difungsikan
mirip dengan sebuah function.
2. Setelah tabel LOGIN_MHS dibuat, barulah procedure untuk menyimpan data user dapat
dibuat, tetapi sebelum procedure dapat dibuat, perlu diingat bahwa dalam procedure yang
akan dibuat, terdapat function untuk membuat password dari mahasiswa. Setelah membuat
tabel, langkah berikutnya adalah membuat function untuk menghasilkan password dengan
format “P”[2 digit angkatan][4 digit nomor urut][1 karakter depan dari nama depan][1
karakter depan dari nama belakang]. function tersebut akan memiliki sebuah parameter untuk
menerima NIM. Kenapa hanya membutuhkan NIM? karena pada umumnya, jika seorang
mahasiswa sudah memiliki NIM, maka mahasiswa tersebut pasti sudah terdaftar dan nama
lengkap dari mahasiswa tersebut sudah pasti tersimpan. Di dalam function, akan dilakukan
pengambilan karakter depan dari nama depan dan nama belakang berdasarkan NIM yang
dimasukkan. Pengkodean untuk function pembuat password dapat dilihat pada halaman
berikutnya.
RETURN @PASS
END
Berdasarkan gambar 4.6, telah dibuktikan bahwa function telah dapat memenuhi kebutuhan
format dari password (“P”[2 digit angkatan][4 digit nomor urut][1 karakter depan dari nama
depan][1 karakter depan dari nama belakang])
3. Setelah tabel dan function yang dibutuhkan sudah jadi, maka langkah terakhir yang perlu
dilakukan adalah membuat procedure untuk menyimpan data user mahasiswa. Procedure
tersebut akan memanggil function GENPWD yang sudah dibuat sebelumnya untuk membuat
password lebih dulu, sebelum melakukan penyimpanan ke dalam tabel LOGIN_MHS.
Pengkodean untuk procedure adalah sebagai berikut.
Pada kode 4.12, terdapat parameter @PNIM_MHS yang digunakan untuk menerima NIM
yang akan dimasukkan ke dalam tabel LOGIN_MHS. Berdasarkan NIM yang dimasukkan ke
@PNIM_MHS juga, akan dibuat sebuah password dengan function GENPWD yang sudah
dibuat sebelumnya. Dengan kata lain, nilai yang dimasukkan ke dalam parameter
@PNIM_MHS milik procedure NEW_MHS_USER, dimasukkan juga ke parameter
@PNIM dari function GENPWD pada saat deklarasi variabel @PWD_MHS agar function
GENPWD dapat membuat password yang akan ditampung oleh variabel @PWD_MHS (nilai
dari salah satu parameter milik procedure digunakan juga pada function di dalam procedure
tersebut). Setelah variabel @PWD_MHS terisi password, barulah data user dimasukkan ke
tabel LOGIN_MHS dengan menggunakan perintah INSERT INTO.
4. Setelah procedure berhasil dibuat, maka langkah berikutnya adalah mencoba penggunaan
procedure untuk memastikan bahwa procedure pasti bisa menyimpan data user mahasiswa
ke dalam tabel LOGIN_MHS. Untuk menguji coba, procedure akan digunakan untuk
menyimpan data user dari NIM “04410150023”, yang sudah tersimpan pada tabel
MAHASISWA.
Sebagai pembuktian apakah data user telah berhasil masuk atau tidak, perintah SELECT
digunakan untuk mengambil data user yang barusan dimasukkan ke dalam tabel
LOGIN_MHS.
Kesamaan nilai dapat dilihat pada kolom PASS di gambar 4.7 dengan hasil uji coba function
pada gambar 4.6, sehingga membuktikan bahwa function di dalam procedure telah berjalan
sesuai dengan kebutuhan, sekaligus membuktikan bahwa procedure telah berhasil
menyimpan data user ke dalam tabel LOGIN_MHS.
PRACTICE
1. Buatlah sebuah Stored Procedure untuk memasukkan data jabatan baru ke dalam tabel JOBS.
Sebelum data jabatan dapat disimpan ke dalam tabel JOBS, ada beberapa peraturan yang
harus dipatuhi:
JOB_ID yang akan disimpan, tidak boleh terdaftar pada tabel JOBS.
MIN_SALARY yang akan disimpan, harus lebih kecil dari MAX_SALARY yang akan
disimpan.
Stored Procedure yang dibuat harus memiliki 4 buah parameter yang dapat menerima nilai
untuk semua kolom pada tabel JOBS.
2. Berdasarkan soal latihan no. 2 pada Bab 2, buatlah sebuah Stored Procedure yang dapat
menghasilkan tampilan program yang sama ketika Stored Procedure dijalankan. Ada
beberapa catatan yang perlu dipenuhi pada saat pembuatan procedure:
Buatlah Function yang digunakan untuk menghitung nilai akhir, dan akan digunakan
pada Stored Procedure.
Buatlah sebuah Function yang digunakan untuk menentukan status (BAIK/KURANG)
dari mahasiswa, dan akan digunakan pada Stored Procedure.
3. Melanjutkan contoh yang sudah dibuat pada kode 4.12, buatlah sebuah procedure yang
mampu membuat dan menyimpan login user dari semua mahasiswa ke dalam tabel
LOGIN_USER.
BAB 5
TRIGGER
Sebuah trigger adalah sebuah jenis khusus dari stored procedure yang akan berjalan secara
otomatis ketika sebuah kejadian, atau istilah yang lebih sederhana, proses, terjadi di server
database. Terdapat 3 (tiga) macam trigger yang dapat dibuat pada T-SQL: DDL (Data
Definition Language), DML (Data Manipulation Language), dan LOGON trigger.
DML trigger adalah trigger yang akan berjalan pada saat seorang pengguna berusaha
melakukan manipulasi data (memasukkan data baru, mengubah, atau menghapus data yang
sudah ada) melalui query/proses DML. Proses atau kejadian DML yang dimaksud adalah saat
query INSERT, UPDATE, atau DELETE dijalankan pada sebuah tabel atau view. DDL trigger
adalah trigger yang berjalan pada saat proses DDL terjadi. DDL trigger umumnya berjalan pada
saat query CREATE, ALTER, atau DROP dijalankan. LOGON trigger adalah trigger yang
berjalan pada saat proses LOGON terjadi. Proses LOGON terjadi setelah seorang user berhasil
melakukan LOGIN (session dari user terjadi). Pada praktikum ini, jenis trigger yang akan
dibahas hanya DML trigger, karena DML trigger adalah trigger yang paling berkaitan dengan
data pada database.
Seperti yang telah dijelaskan sebelumnya, DML trigger adalah trigger yang terjadi pada
saat terjadi manipulasi data yang tersimpan pada sebuah tabel atau view, dan trigger sendiri
adalah obyek T-SQL yang akan berjalan otomatis pada saat proses tertentu dijalankan. Berikut
adalah struktur dasar pengkodean untuk membuat sebuah DML trigger.
<table_name>
Bagian ini berisi nama tabel yang akan “dipasang” DML trigger, atau dengan kata lain tabel
yang menjadi tempat perintah DML dijalankan. Nama tabel juga dapat diganti dengan nama
view.
<[FOR|AFTER|INSTEAD OF]>
Bagian ini harus berisi salah satu dari keyword FOR, AFTER, atau INSTEAD OF.
FOR/AFTER/INSTEAD OF adalah kondisi yang menentukan kapan DML trigger akan
dijalankan, dengan kata lain timing dari jalannya DML trigger. Seperti yang sudah dijelaskan
sebelumnya, sebuah DML trigger berjalan pada saat terjadi proses atau query DML pada
sebuah tabel, sedangkan timing ini menjelaskan kapan pada saat sebuah query DML
dijalankan, proses pada trigger dijalankan. FOR/AFTER akan membuat proses pada trigger
dijalankan setelah query DML selesai dijalankan, sedangkan INSTEAD OF membuat proses
pada trigger dijalankan MENGGANTIKAN query DML (tertulis menggantikan, karena
query DML tidak pernah dijalankan).
<[DELETE][,][INSERT][,][UPDATE]>
Bagian ini berisi jenis query DML yang akan membuat DML trigger berjalan. Minimal harus
ada 1 (satu) jenis query DML yang dituliskan di bagian ini, tetapi tidak menutup
kemungkinan untuk menuliskan lebih dari 1 (satu) jenis query DML. Penulisan lebih dari 1
(satu) jenis query DML dipisahkan dengan simbol koma (“,”)
<process_code>
Bagian ini berisi proses yang digambarkan dengan pengkodean atau dengan kata lain, bagian
ini berisi konten dari trigger. Proses atau pengkodean yang dituliskan pada bagian ini mirip
dengan proses yang dilakukan pada sebuah procedure, yaitu pengkodean pada trigger ini
tidak mengembalikan/menghasilkan sebuah nilai. Pada saat melakukan pengkodean proses
dari DML trigger, terdapat 2 (dua) buah tabel logis yang hanya dapat diakses oleh proses
DML trigger, yaitu tabel INSERTED dan tabel DELETED. Penggunaan dari tabel
INSERTED dan DELETED akan dijelaskan pada penjelasan dan contoh berikutnya.
Sama seperti pada function dan procedure, sebuah trigger yang sudah berhasil dibuat,
masih dapat dirubah konten/prosesnya. Untuk mengubah konten di dalam trigger, digunakan
perintah ALTER. Struktur dasar pengkodean untuk mengubah konten dari DML trigger dapat
dilihat pada halaman berikutnya.
Seperti terlihat pada kode 5.2, untuk merubah konten/proses dari sebuah trigger, ganti keyword
CREATE menjadi ALTER. Perlu diperhatikan bahwa, nama dari trigger tidak boleh dirubah.
Setelah sebuah trigger tidak diperlukan lagi, maka trigger tersebut dapat dihapus dengan
menggunakan perintah DROP TRIGGER. Berikut adalah struktur dasar pengkodean untuk
menghapus trigger.
Selain dengan perintah pada kode 5.3, untuk menghapus DML trigger, bisa juga dengan
menghapus tabel yang dituliskan pada bagian ON <table_name> dari DML trigger yang akan
dihapus. Seperti yang sudah dijelaskan sebelumnya, sebuah DML trigger akan “terpasang” pada
sebuah tabel, sehingga jika tabel tersebut dihapus, maka semua trigger yang dipasang pada tabel
tersebut juga akan ikut terhapus.
FOR|AFTER vs INSTEAD OF
Seperti yang sudah dijelaskan sebelumnya, selain jenis query DML yang dijalankan,
sebuah DML trigger juga memerlukan timing untuk menentukan kapan proses pada DML
trigger akan berjalan. Timing FOR/AFTER akan menjalankan proses pada trigger setelah query
DML selesai dijalankan, sedangkan timing INSTEAD OF akan membuat proses pada DML
trigger MENGGANTIKAN query DML, sehingga query DML tidak pernah dijalankan. Sebagai
pembuktian, beberapa contoh dari trigger yang menggunakan timing AFTER dan timing
INSTEAD OF akan dibuat.
Sebagai contoh pertama, sebuah trigger akan dibuat untuk menampilkan keterangan “ada
data masuk tabel jobs” pada saat terjadi proses pemasukan data yang berhasil ke dalam tabel
JOBS. Struktur pengkodean untuk memenuhi kebutuhan trigger tersebut adalah sebagai berikut:
Kode 5.5 Query DML untuk uji coba trigger pada kode 5.4
Berikut adalah hasil eksekusi query DML INSERT pada kode 5.5
Pada gambar 5.1, dapat dilihat bahwa pesan yang dicetak melalui trigger juga ikut tampil, yang
membuktikan bahwa trigger telah berjalan dengan baik. Untuk membuktikan bahwa timing
AFTER dari trigger juga telah berjalan, dapat dilakukan dengan cara melakukan query SELECT
berdasarkan data yang barusan dimasukkan. Jika data sudah tersimpan, maka timing AFTER
telah berjalan (seperti yang sudah dijelaskan sebelumnya, timing AFTER membuat proses
trigger berjalan setelah query DML berhasil dijalankan). Hasil SELECT pada tabel JOBS
dengan kondisi JOB_ID “TEK_TI” adalah sebagai berikut.
Gambar 5.2 Pembuktian bahwa data sudah masuk ke dalam tabel JOBS
INSTEAD OF INSERT mendefinisikan bahwa proses pada trigger ini akan menggantikan
query DML INSERT yang dijalankan pada tabel PROGRAM_STUDI.
Setelah pembuatan DML trigger selesai, berikutnya adalah melakukan pembuktian apakah
trigger telah bekerja dengan baik atau tidak. Sama seperti contoh trigger pada kode 5.4, karena
trigger ini berjalan pada saat query DML INSERT dieksekusi, maka untuk menguji trigger
INSTEAD OF ini, digunakan query INSERT INTO ke tabel PROGRAM_STUDI. Berikut
adalah contoh query sekaligus dengan hasil eksekusi dari query INSERT.
Pada gambar 5.3, pesan yang dicetak melalui trigger PRODI_INFO pada kode 5.6 telah tampil,
maka trigger telah berfungsi dengan baik. Pembuktian berikutnya adalah membuktikan bahwa
data yang seharusnya telah dimasukkan ke dalam tabel PROGRAM_STUDI dengan perintah
INSERT INTO, tidak berhasil tersimpan di dalam tabel. Sama seperti contoh sebelumnya,
pembuktian dilakukan dengan melakukan query SELECT berdasarkan data yang akan
dimasukkan.
Pada gambar 5.4, dapat dilihat bahwa data yang dimasukkan ke dalam tabel melalui query
INSERT gambar 5.3 tidak berhasil tersimpan pada tabel PROGRAM_STUDI, karena query
INSERT “digantikan” dengan proses pada trigger (query INSERT tidak pernah dijalankan).
Pada 2 (dua) contoh di atas, hanya terdapat contoh query DML INSERT yang digunakan
pada 2 (dua) timing yang berbeda (AFTER dan INSTEAD OF). Bagaimana dengan query DML
yang lain (UPDATE dan DELETE)? 2 (dua) timing dari trigger yang sudah ditunjukkan pada
contoh sebelumnya dapat dikombinasikan dengan query DML yang lain. berikut adalah tabel
untuk menggambarkan hasil kombinasi query DML dengan timing dari trigger.
Tabel 5.1 Hasil kombinasi jenis query DML dengan timing pada trigger
DML/Timin
FOR/AFTER INSTEAD OF
g
Proses pada trigger akan berjalan Proses pada trigger akan berjalan MENGGANTIKAN
INSERT setelah query DML INSERT berhasil query DML INSERT (query DML INSERT tidak akan
dieksekusi dieksekusi)
Proses pada trigger akan berjalan Proses pada trigger akan berjalan MENGGANTIKAN
UPDATE setelah query DML UPDATE berhasil query DML UPDATE (query DML UPDATE tidak akan
dieksekusi dieksekusi)
Proses pada trigger akan berjalan Proses pada trigger akan berjalan MENGGANTIKAN
DELETE setelah query DML DELETE berhasil query DML DELETE (query DML DELETE tidak akan
dieksekusi dieksekusi)
adanya proses penghapusan (DELETE) dan pemasukan data baru (INSERT), maka pada saat
DML trigger menggunakan query DML UPDATE sebagai kondisi dari trigger, maka trigger
tersebut dapat mengakses tabel INSERTED dan DELETED. Pada saat query DML UPDATE,
tabel INSERTED akan berisi data baru yang akan dimasukkan pada query UPDATE, sedangkan
tabel DELETED akan berisi data lama yang akan diganti pada query UPDATE.
Seperti yang sudah dituliskan sebelumnya, INSERTED dan DELETED adalah sebuah
tabel, dan sebuah tabel pasti terdiri atas baris dan kolom. Struktur kolom pada tabel INSERTED
dan DELETED akan sama dengan kolom yang dituliskan pada bagian ON pada saat DML
trigger dibuat. Contoh (berdasarkan struktur tabel yang digunakan pada praktikum), jika DML
trigger dibuat dengan kondisi ON EMPLOYEES, maka tabel INSERTED dan DELETED akan
memiliki struktur kolom yang sama dengan tabel EMPLOYEES, jika kondisi DML TRIGGER
adalah ON MAHASISWA, maka tabel INSERTED dan DELETED akan memiliki struktur tabel
yang sama dengan tabel MAHASISWA.
Lalu bagaimana dengan baris dari tabel INSERTED dan DELETED? Isi atau baris data di
dalam tabel INSERTED dan DELETED sangat bergantung pada query DML yang dijalankan.
Jika query DML yang dijalankan (INSERT, UPDATE, atau DELETE) akan mempengaruhi 1
baris saja, maka isi dari tabel INSERTED atau DELETED adalah 1 baris yang terpengaruh
tersebut, sedangkan jika query DML yang dijalankan akan mempengaruhi lebih dari 1 baris data,
maka isi dari tabel INSERTED atau DELETED akan sama dengan baris-baris yang terpengaruh
query DML tersebut. penjelasan yang lebih sederhana adalah sebagai berikut:
Tabel 5.2 Isi tabel INSERTED dan DELETED berdasarkan query DML pada trigger
DML/Tabel
INSERTED DELETED
Logika
akan berisi data yang akan/telah
INSERT -
dimasukkan ke dalam tabel
akan berisi data lama pada tabel yang akan
akan berisi data baru yang dituliskan
UPDATE terpengaruh/ter-update query DML
pada query DML UPDATE
UPDATE
akan berisi data yang akan/telah dihapus
DELETE -
dari tabel
Data-data dalam tabel INSERTED dan DELETED inilah yang umumnya diproses pada trigger.
Berikut adalah beberapa contoh penggunaan tabel INSERTED dan DELETED pada trigger.
Sebagai contoh awal, sebuah trigger akan dibuat untuk mencetak ulang data yang telah
dimasukkan ke dalam tabel PROGRAM_STUDI. Jika sebelumnya, trigger pada kode 5.4 telah
berhasil dijalankan dan dibuat, maka sangat disarankan menghapus trigger tersebut lebih dulu
dengan perintah DROP TRIGGER untuk mencegah terjadinya proses pada trigger yang saling
bersilangan. Karena trigger ini berfungsi untuk mencetak ulang data yang telah dimasukkan ke
dalam tabel PROGRAM_STUDI, maka trigger ini akan menggunakan timing AFTER yang
dikombinasi dengan query DML INSERT, dan trigger ini akan dipasangkan pada tabel
PROGRAM_STUDI. Sebagai sumber data yang akan dicetak, trigger ini akan mengakses tabel
INSERTED (karena query DML yang menjadi kondisi adalah DML INSERT). Pengkodean
untuk trigger ini adalah sebagai berikut.
Pada gambar 5.5, dapat dilihat bahwa trigger mencetak nilai yang telah dimasukkan dengan
query INSERT INTO (ada kesamaan antara hasil cetak trigger dengan nilai yang dimasukkan
melalui query INSERT). Hal ini membuktikan isi dari tabel INSERTED sudah sesuai dengan
query DML INSERT.
Sebagai contoh berikutnya, sebuah trigger akan dibuat untuk memeriksa apakah data
pekerjaan yang akan dihapus, masih digunakan pada tabel lain (tabel yang
mereferensi/menggunakan tabel JOBS adalah tabel JOB_HISTORY dan tabel EMPLOYEES).
Jika data pekerjaan yang akan dihapus, masih digunakan pada tabel EMPLOYEES atau tabel
JOBS, maka data tersebut tidak boleh dihapus, sedangkan jika data tersebut sudah tidak
digunakan, maka data tersebut akan dihapus. karena ada kondisi pemeriksaan sebelum
menghapus, maka trigger harus dipastikan berjalan sebelum data dihapus (INSTEAD OF
DELETE). Struktur pengkodean untuk pembuatan trigger adalah sebagai berikut.
Tambahan, proses yang terjadi di dalam sebuah trigger dapat juga memanggil obyek T_SQL lain.
seperti procedure atau function yang sudah dibuat sebelumnya, tetapi sebaliknya, di dalam
sebuah procedure atau function, TIDAK BISA mengandung sebuah trigger.
PRACTICE
1. Buatlah sebuah Trigger yang akan berjalan pada saat sebuah data masuk ke dalam tabel
KEGIATAN. Trigger ini berfungsi untuk menghubungkan posisi “Ketua Panitia” yang sudah
ada pada tabel JENIS_POS_EVENT dengan data kegiatan yang baru saja dimasukkan ke
dalam DETAIL_JENIS_POSISI_EVENT (masukkan data “ketua panitia” dan data kegiatan
yang barusan dimasukkan DETAIL_JENIS_POSISI_EVENT, dan beri jumlah SKKM 3).
2. Buatlah sebuah Trigger yang akan berjalan sebelum melakukan penghapusan data mahasiswa.
Trigger ini berfungsi untuk memeriksa apakah mahasiswa yang akan dihapus, memiliki data
pada tabel NILAI, MAHASISWA_BERPRESTASI, dan/atau KEAKTIFAN_MAHASISWA.
Jika data mahasiswa ada pada salah satu/semua tabel, maka data nilai mahasiswa tersebut
HARUS DIHAPUS LEBIH DULU, barulah menghapus data asli mahasiswa.
BAB 6
INTRODUCING VISUAL BASIC .NET
Ketika menjalankan Visual Studio, yang pertama kali muncul adalah jendela selamat datang.
Pada jendela ini ada beberapa pilihan seperti New Project untuk membuat projek baru, Open
Project untuk membuka projek yang sudah pernah dibuat sebelumnya, Recent Project untuk
membuka project yang terakhir dibuka.
Form Window
Project Explorer
Toolbox
Properties
Project Explorer
Project explorer pada Gambas berfungsi untuk menampilkan daftar komponen yang
dimiliki oleh suatu project yang sedang dibuat. Komponen – komponen tersebut dapat
berupa classes, forms, modules, dan data
Form Window
Form window merupakan tempat untuk meletakkan suatu objek atau kontrol yang
dibutuhkan seperti label, button, text, dan lain sebagainya yang digunakan untuk
mendesain tampilan atau interface dari aplikasi yang sedang dibuat. Untuk menambahkan
form pada menu Project Add Windows Form
Properties Window
Berisi daftar properti untuk objek (form atau kontrol) yang dipilih dan berfungsi untuk
mengatur karakteristiknya seperti nama, ukuran, dan lain–lain. Tiap objek dalam toolbox
memiliki properti yang belum tentu sama dengan objek yang lain, hal ini dikarenakan tiap
objek memiliki fungsi yang berbeda dengan objek yang lain.
Area Source Code merupakan tempat untuk menuliskan kode – kode program untuk objek
yang dibuat. Jendela ini bisa dimunculkan melalui menu View atau dengan menekan Ctrl+Alt+0.
A. Komentar (Comment)
Komentar adalah suatu teks yang dituliskan dalam badan program namun tidak akan
dikerjakan atau di eksekusi oleh program meskipun berisi keyword atau perintah program.
Baris komentar sangat bermanfaat untuk memudahkan programmer program untuk
mendokumentasikan perintah pada program. Hal ini juga berguna untuk menelusuri error atau
kesalahan dalam alur program ketika program mengalami error.
Contoh:
B. Variabel
Variable adalah lokasi atau tempat penyimpanan sementara dalam memori untuk data
program. Dalam bahasa Basic, untuk mendeklarasikan variable harus mengikuti aturan sebagai
berikut:
Harus diawali dengan huruf
Tidak dapat berisi spasi atau karakter kosong
Panjang variable tidak lebih dari 255 karakter
Tidak boleh terdapat duplikasi nama.
Tidak boleh mengandung reserverd word.
Deklarasikan Variabel diawali dengan DIM . Deklarasi tersebut berlaku dalam suatu
prosedur atau fungsi, dimana variable tersebut dideklarasikan. DIM harus dideklarasikan di
permulaan prosedur atau fungsi.
Contoh :
DIM (variable) as (type Data)
DIM (variable) [array] as (type data)
Dim nilai as Integer
Program Studi S1 Sistem Informasi 84
August 6, 2018 [MODUL PRAKTIKUM PEMROGRAMAN BASIS DATA]
Penggunaan deklarasi variabel dibagi menjadi dua yaitu, variabel lokal dan variabel global.
Deklarasi variabel lokal hanya dikenali didalam lingkup yang kecil yaitu pada Sub penulisan
source code. Deklarasi variabel global dapat dikenali disemua Sub penulisan source code
didalam 1(satu) class.
Variabel Global
Variabel Lokal
C. Tipe Data
Tipe data dalam bahasa basic yang bisa digunakan secara umum programer dalam membuat
program di Visual Basic. Tipe data tersebut adalah :
Boolean : Tipe data untuk operator logika bernilai TRUE dan FALSE
Integer : Tipe data untuk menampung nilai ANGKA
String : Tipe data untuk menampung nilai huruf dan dapat berupa kalimat
Float : Tipe data untuk menampung nilai angka pecahan
Short : Tipe data untuk menampung nilai ANGKA
D. Event
Event dapat diartikan sebagai suatu kemungkinan yang akan dilakukan oleh user atau
pengguna program. Contoh dari event dapat berupa penekanan tombol pada keyboard atau
melakukan klik pada mouse pada suatu area tertentu. Dengan kata lain, event adalah sebuah
pengaturan aksi yang dilakukan sebuah object. Berikut ini adalah beberapa event yang sering
digunakan.
Event yang terjadi pada penekanan tombol keyboard, diantaranya adalah :
Keypress : terjadi ketika penekanan tombol pada keyboard
KeyUp : terjadi ketika pelepasan tombol pada keyboard
Sebagai catatan, semua event di Visual Basic terjadi secara otomatis pada saat kita men-
double click pada object yang kita maksud. Sebagai contoh apabila kita ingin memberikan event
pada button maka kita cukup men-double click pada button tersebut dan otomatis akan terjadi
generate code untuk event tersebut.
E. Property
Property adalah karakteristik atribut-atribut yang melekat pada suatu object. Atribut atau
karakteristik dapat berupa nama object, warna, tinggi, dan sebagainya. Berikut ini adalah
beberapa properti yang umum terdapat pada sebuah object.
Name : tentang nama object itu sendiri
Alignment : berisi pengaturan posisi teks atau isi yang terdapat pada object
Backcolor : tentang warna latar object
PRACTICE
1. Buatlah sebuah window form seperti berikut :
Fungsi dari form ini adalah untuk melakukan konversi suhu dari celcius, ke skala satuan suhu
yang lain, sesuai dengan satuan yang dipilih (reamur, fahrenheit, kelvin). Cara kerja dari
form ini adalah sebagai berikut:
Pada saat form ini dijalankan, pilihan konversi harus diisi dengan 3 (tiga) pilihan, yaitu
Reamur, Fahrenheit, dan Kelvin.
Pengguna harus mengisi nilai suhu dalam celcius dan memilih pilihan konversi sebelum
melakukan konversi (menekan tombol “Lakukan Konversi Suhu”). Jika salah satu belum
dilakukan, maka tidak ada pemrosesan pada saat tombol “Lakukan Konversi Suhu”
ditekan.
Setelah pengguna mengisi nilai suhu celcius dan memilih pilihan konversi, pengguna
dapat melihat hasil konversi dengan menekan tombol “Lakukan Konversi Suhu”. Hasil
konversi akan ditampilkan pada label LBLHasil.
Selain menampilkan hasil konversi, tombol juga berfungsi untuk memasukkan proses
konversi ke dalam Histori Konversi dengan format “nn celcius = kk ss”
Keterangan :
nn = nilai celcius yang dimasukkan; kk = nilai hasil konversi; ss = satuan konversi yang
dipilih.
Fungsi dari form ini adalah untuk menampilkan bentuk biner dari angka 1 sampai dengan
batasan angka yang dimasukkan. Cara kerja dari form ini adalah sebagai berikut:
Pengguna mengisi batasan angka lalu menekan tombol ENTER untuk menampilkan
bentuk biner dari angka 1 sampai dengan batasan angka yang dimasukkan.
Jika batasan angka tidak diisi atau batasan angka diisi dengan angka desimal
(mengandung koma), lalu pengguna menekan ENTER, maka form akan mengeluarkan
pesan “Batasan angka tidak boleh kosong dan harus berupa angka bulat.”.
Tampilan form setelah digunakan:
Tampilan pesan jika batasan angka tidak diisi atau batasan angka diisi dengan angka desimal
(mengandung koma) :
BAB 7
ARRAY IN VISUAL BASIC .NET
PRACTICE
BAB 8
CONNECTING TO DATABASE PART 1
CONNECTION OBJECT
CONNECTED ENVIRONMENT
PRACTICE
BAB 9
CONNECTING TO DATABASE PART 2
DATASET
DATATABLE
DISCONNECTED ENVIRONMENT
PRACTICE
BAB 10
USING T-SQL OBJECT WITH VISUAL BASIC .NET
PRACTICE
REFERENCES