Thursday, March 8, 2007

Create Procedure in MySQL

Alhamdulillah, hari ini dapet ilmu baru! Biasanya aq kerja pake DBMS Oracle, tapi coz kebetulan TA butuh database dan ga mungkin install Oracle di kompie jelek ini, terpaksa make MySQL. Dan ternyata, sintaks2 di MySQL tuh banyak yang beda sama Oracle. seharian ini cuman belajar bikin prosedur! cukup rumit ternyata :))

So, biasanya kalo di t4 kerja yang make Oracle, untuk proses2 yang butuh prosedur, aq tinggal bikin aja script "begin ..... end" atau "declare...begin...end;" tanpa "create procedure". Tapi ternyata di MySQL ga bisa semudah itu! setahuku harus bikin2 prosedur! dan untuk bikin prosedur pun tidak semudah biasanya. coz kalo di MySQL, double quote tuh dianggap sebagai akhir dari sebuah query. sementara itu, di dalem Prosedur kan umumnya banyak tuh pemakaian tanda ";" berhubung proses yang dikerjakan tidak cuman 1. Nah, untuk itu, solusinya bisa dengan cara seperti ini :
delimiter $$;

query1$$
query2$$

delimiter ;$$
Dengan penggunaan delimiter spt itu, tanda ";" tidak akan dibaca sebagai akhir dari sebuah query melainkan tanda "$$" (bisa diganti dengan apa saja) yang dibaca sebagai akhir dari sebuah query.

Yang berbeda lagi adalah ketika kita mau menjalankan proses looping sesuai data yang diperoleh dari fungsi "select". kalo di Oracle, kita bisa dengan simple bikin code seperti ini:
for item in (select * from t where ....)
loop
.....
end loop;
Tapi di MySQL tidak mengenal syntax "for" seperti itu. MySQL cuman mengenal loopnya aja, dengan karakter yang berbeda pula. Setelah nyari cukup lama, akhirnya dapet juga rujukan, yaitu dengan memakai yang namanya "cursor". data yang akan dihasilkan dari "select" tsb akan dimasukkan ke dalam suatu cursor, kemudian untuk memprosesnya digunakan fungsi "fetch" yang akan mereturn baris2 selanjutnya. Tentunya biar semua data bisa diproses, dilakukan looping hingga tidak ada lagi baris yang direturn. Berikut contoh prosedur yang aku bikin sehubungan dengan kerjaan TA ku :)
DELIMITER $$;

DROP PROCEDURE IF EXISTS `gir`.`deleteSampah`$$

CREATE PROCEDURE `gir`.`deleteSampah` (IN cc VARCHAR(10))
BEGIN
declare temp_rc,temp_cc1, temp_adm1,temp_cc2,temp_nt,temp_adm2,
temp_full_name,temp_fc varchar(50);

declare a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p varchar(50);
declare no_more_rows boolean default FALSE;
declare items cursor for
select * from geonames
where CC1 = cc
order by full_name,rc,cc1,adm1,adm2,cc2,nt,fc,modify_date desc;
declare continue handler for not found
set no_more_rows := TRUE;set temp_rc ="temp", temp_cc1 ='temp',
temp_adm1 ='temp', temp_cc2 ='temp',temp_nt ='temp',

temp_adm2 ='temp',temp_full_name ='temp',temp_fc = 'temp';

open items;
itemloop: loop

if no_more_rows then
close items;
leave itemloop;
end if;

fetch items into a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;
if (n = temp_full_name and a = temp_rc and
f = temp_cc1 and g = temp_adm1 and i = temp_cc2
and j = temp_nt and h =temp_adm2 and e = temp_fc)
then
delete from geonames
where full_name = n and rc = a and cc1 = f
and adm1 = g and cc2 = i and nt = j and adm2 = h
and lati = b and longi = c and utm = d and fc = e
and short_form = k and generic = l and
short_name= m and full_name_nd = o
and modify_date = p;
else
set temp_full_name = n , temp_rc = a , temp_cc1 = f,
temp_adm1 = g, temp_cc2 = i , temp_nt = j ,
temp_adm2 = h ,temp_fc = e;
end if;
end loop itemloop;
END$$

DELIMITER ;$$
Yup.....Alhamdulillah dengan procedure tersebut, berhasil ngebuang sampah2 yang ada di database ku, dari 5,8 juta records, sekarang tinggal .... (ntar...baru sebagian dikerjain :p)

thanks bwt Mr. Roland Bouman atas referensinya ;)

No comments: