SlideShare una empresa de Scribd logo
1 de 22
Descargar para leer sin conexión
Stored Procedure  Function (pada
PostgreSQL)
M. Ammar Shadiq
Ilmu Komputer  Universitas Pendidikan Indonesia, Bandung
5 Mei 2008
Pertama-tama anda harus menginisiasikan procedural language (bahasa prosedural) pada
postgreSQL yang dinamakan PL/pgsql, perintahnya :
CREATE LANGUAGE plpgsql;

TABEL YANG DIGUNAKAN :

DERET1 : (NILAI INTEGER)
CREATE TABLE deret1 (nilai integer);

DERET2 : (NILAI INTEGER, KOMENTAR CHARACTER(8))
CREATE TABLE deret2 (nilai integer, komentar character(8));
Dengan Dummy Data : (1), (2), (3), (4),(5)
       INSERT INTO deret2 (nilai) VALUES (1),(2),(3),(4),(5);

ACCOUNT : (NAMA CHARACTER(50), SALDO INTEGER, CABANG CHARACT ER(50))
CREATE TABLE account (nama character(50),saldo integer,cabang
character(50);
Dengan Dummy Data : (shadiq, Rp. 100.000, Bogor), (Alice, Rp. 1.000.000, Bogor), (Bob, Rp. 700.000,
Bandung), (Wally, Rp. 500.000, Bandung)
INSERT INTO account VALUES
('shadiq',100000,'Bogor'),
('Alice',1000000,'Bogor'),
('Bob',700000,'Bandung'),
('Wally',500000,'Bandung');




                                                                    1|S tored Proc edure
PENDAHULUAN

Contoh 1 :
Fungsi untuk mengisi field nim pada tabel deret1 dengan nilai deret 0, 2, 4, ... , 100.

CREATE OR REPLACE FUNCTION isi_deret1() RETURNS void AS $$
DECLARE
      counter integer;
BEGIN
      counter := 0;
      loop
            insert into deret1(nilai) values (counter);
            counter := counter + 2;
            if (counter > 100) then
                  exit;
            end if;
      end loop;
      return;
END;
$$ LANGUAGE 'plpgsql';


Eksekusi fungsi diatas :

SELECT isi_deret1();

        isi_deret1
        ---------

        (1 row)

Cek isi tabel deret1 yang sudah di modifikasi :
SELECT * FROM deret1;




Untuk melihat fungsi yang ada pada PostgreSQL anda dapat menuliskan perintah berikut :

Melihat semua fungsi
df

Melihat fungsi tertentu
df <nama_fungsi>

Melihat isi fungsi
df+ <nama_fungsi>




                                                                  2|S tored Proc edure
STRUKTUR FUNGSI PADA PL/PGSQL
CREATE [OR REPLACE] FUNCTION nama_fungsi ( [ argtype [, ...] ] )
RETURNS return_type

       AS $$definition$$

       LANGUAGE langname

       [ WITH ( attribute [, ...] ) ]


MENGHAPUS FUNGSI
DROP FUNCTION nama_fungsi(paramater[, parameter[, parameter ... );

Ex :

DROP FUNCTION isi_deret11();

BADAN FUNGSI
DECLARE
      /* deklarasi variabel, type dan subprogram lokal */
BEGIN
      /* prosedural dan SQL masuk disini */
      / blok ini yang wajib */
END;



DEKLARASI VARIABEL :
Contoh :
DECLARE
v_counter INTEGER;
v_nim CHAR(5);
v_nama VARCHAR(2);
v_nilai NUMBER;
v_nim_2 mahasiswa.nim%TYPE              /* tipe variabel mengikuti tipe field mahasiswa.nim */


mengapa menggunakan huruf depan v_? Supaya tidak bentrok dengan nama field. Contoh :

INSERT INTO      mahasiswa (nim, nama) VALUES (v_nim, v_nama);

Nilai variabel juga dapat diinisiasikan saat pembuatannya. Contoh :

v_nilai_minimum INTEGER := 30;

Deklarasi Variabel pada Pembuatan Fungsi :

Pendeklarasian variabel dapat juga dilakukan pada pembuatan fungsi, dengan konsekuensi varibel
tersebut HARUS menjadi parameter input atau output.




                                                                      3|S tored Proc edure
Contoh 2 :
Fungsi untuk mengisi field nim pada tabel deret1 dengan nilai deret 0 s/d nilai yang di
tentukan dengan penambahan nilai +2 tiap iterasi.

CREATE OR REPLACE FUNCTION isi_deret2(sampai_dengan integer) RETURNS void
AS $$
DECLARE
      counter integer;
BEGIN
      counter := 0;
      loop
            insert into deret1(nilai) values (counter);
            counter := counter + 2;
            if (counter>sampai_dengan) then
                  exit;
            end if;
      end loop;
      return;
END;
$$ LANGUAGE 'plpgsql';



Pengeksekusian dilakukan dengan memasukkan parameter.

SELECT isi_deret2(60);

        isi_deret2
        ---------

        (1 row)

Fungsi diatas akan memasukkan nilai 0, 2, 4, ..., 60 pada tabel deret1.

Untuk menghapus fungsi dengan parameter masukan menggunakan perintah :

DROP FUNCTION isi_deret2(integer);

JENIS-JENIS VARIABEL PARAMETER FUNGSI.
Ada tiga jenis parameter :

IN      : variabel input (default)

OUT     : variabel output

INOUT : variabel input dan output

Jika anda memperhatikan contoh-contoh fungsi diatas, pada waktu pendeklarasian fungsi ada
parameter output yang ditandakan dengan RETURNS tipe_data.

CREATE OR REPLACE FUNCTION isi_deret2(sampai_dengan integer) RETURNS void
AS $$..........




                                                                   4|S tored Proc edure
Pada contoh diatas karena fungsi tersebut tidak menghasilkan suatu nilai, maka parameter
outputnya diisikan dengan tipe data VOID*.

* Fungsi dengan parameter output void artinya tidak menghasilkan suatu nilai (tidak mengembalikan nilai) atau biasa disebut fungsi
kosong. void : kekosongan, kehampaan (Kamus Inggris-Indonesia, John M. Echoles)


Untuk lebih jelasnya, perhatikan contoh-contoh fungsi dibawah ini :

Contoh 3 :
CREATE FUNCTION contoh_parameter_1 (IN sampai_dengan integer) RETURNS void
AS $$
DECLARE
      counter integer;
BEGIN
      counter := 0;
      loop
            insert into deret1(nilai) values (counter);
            counter := counter + 2;
            if (counter>sampai_dengan) then
                  exit;
            end if;
      end loop;
      return;
END;
$$ LANGUAGE 'plpgsql';
Fungsi ini sama dengan fungsi isi_deret2(integer) namun dengan penulisan yang berbeda.
Karena sebenarnya IN adalah parameter default, sebenarnya tidak perlu di tuliskan, hal ini
dimaksudkan agar dapat dimengerti.

Contoh 4 :
CREATE FUNCTION contoh_parameter_2 (IN sampai_dengan integer) RETURNS
integer AS $$
DECLARE
        counter integer;
BEGIN
        counter := 0;
        loop
               insert into deret1(nilai) values (counter);
               counter := counter + 2;
               if (counter>sampai_dengan) then
                         exit;
               end if;
        end loop;
        RETURN counter;
END;
$$ LANGUAGE 'plpgsql';
Fungsi ini memberi nilai keluaran yaitu counter dengan tipe data integer. Saat ada nilai keluaran,
konsekwensinya harus ada deklarasi RETURN yang menentukan nilai apa yang di keluarkan.




                                                                                             5|S tored Proc edure
Contoh 5 :
CREATE FUNCTION contoh_parameter_3 (IN sampai_dengan integer, OUT
keluaran_sd integer) AS $$
DECLARE
        counter integer;
BEGIN
        counter := 0;
        loop
                insert into deret1(nilai) values (counter);
                counter := counter + 2;
                if (counter>sampai_dengan) then
                        exit;
                end if;
        end loop;
        keluaran_sd := counter;
END;
$$ LANGUAGE 'plpgsql';
Fungsi ini sama dengan fungsi contoh_parameter_2, namun tanpa deklarasi RETURNS pada awal
deklarasi fungsi, juga tanpa deklarasi RETURN pada badan fungsi. Sebagai ganti RETURN, digunakan
pengisian nilai variabel keluaran_sd dengan nilai variabel counter. Kita tetap dapat
menggunakan statement RETURN pada badan fungsi, namun hal ini akan menyebabkan redudansi.
Pilih salah satu saja.

Catatan : perhatikan perbedaan RETURN pada badan fungsi dan RETURNS pada deklarasi fungsi.

Dengan fungsi seperti ini, pemanggilannya dilakukan dengan hanya memasukkan nilai variabel
input saja.

SELECT contoh_parameter_3(60);

          contoh_parameter_3
          ------------------
                          62
          (1 row)

Pertanyaan : Kenapa hasil yang dikeluarkan 62 ?
Jawaban    : perhatikan bahwa fungsi diatas melakukan proses tiap iterasi dengan membandingkan variabel counter. Saat iterasi
             sebelum terakhir (misal 60) fungsi membandingkan jika variabel counter > 60, karena nilai variabel counter belum melebihi
             60 (tetapi sama dengan) maka iterasi dilakukan sekali lagi dan nilai variabel counter bertambah menjadi 62. Saat fungsi
             melakukan perbandingan kembali (counter > 60 [62>60]), maka kondisi tidak terpenuhi, tetapi nilai variabel counter
             adalah 62. Oleh karena itu hasil yang dikeluarkan adalah 62 bukan 60.



Contoh 6 :
Fungsi yang menghasilkan dua keluaran :
CREATE FUNCTION contoh_parameter_4 (IN sampai_dengan integer, OUT
keluaran_sd integer, OUT banyaknya_data integer) AS $$
DECLARE
      counter1 integer;
      counter2 integer;
BEGIN
      counter1 := 0;


                                                                                            6|S tored Proc edure
counter2 := 0;
        loop
              insert into deret1(nilai) values (counter1);
              counter1 := counter1 + 2; -- memasukkan nilai genap
              counter2 := counter2 + 1; -- menghitung banyaknya iterasi
              if (counter1>sampai_dengan) then
                    exit;
              end if;
        end loop;
        keluaran_sd := counter1;
        banyaknya_data := counter2;
END;
$$ LANGUAGE 'plpgsql';
Jika anda mengeksekusi fungsi ini dengan Variabel masukan sampai_dengan = 60, maka nilai
variabel keluarannya adalah keluaran_sd = 62, dan variabel banyaknya_data = 31 (0...60).

SELECT contoh_parameter_4(60);

        contoh_parameter_4
        ------------------
              (62,31)
        (1 row)

Contoh 7 :
CREATE FUNCTION contoh_parameter_5 (INOUT sampai_dengan integer) AS $$
DECLARE
      counter integer;
BEGIN
      counter := 0;
      loop
            insert into deret1(nilai) values (counter);
            counter := counter + 2;
            if (counter>sampai_dengan) then
                  exit;
            end if;
      end loop;
      sampai_dengan := counter;
END;
$$ LANGUAGE 'plpgsql';
Dapat di perhatikan pada fungsi diatas, variabel input dan outputnya sama yaitu variabel
sampai_dengan.

SELECT contoh_parameter_5(60);

        contoh_parameter_5
        ------------------
                        62
        (1 row)




                                                                    7|S tored Proc edure
BATASAN-BATASAN
Variabel input : tidak dapat diubah

Variabel output : tidak dapat di jadikan nilai referensi pada variabel lain.

Contoh :

CREATE FUNCTION contoh_parameter_salah (IN p_in integer, OUT p_out integer,
INOUT p_inout integer) AS $$
DECLARE
      local integer;
BEGIN
      local := p_in;
      local := p_inout;
      p_out := p_in;
      p_out := local
      p_out := 5;
      p_inout := p_in;
      p_inout := local;
      p_inout := 5;

        p_in := 5;               --   ERROR,   INPUT tidak boleh diisi
        p_in := local;           --   ERROR,   INPUT tidak boleh diisi
        p_in := p_inout;         --   ERROR,   INPUT tidak boleh diisi
        local := p_out;          --   ERROR,   OUTPUT tidak boleh digunakan
        p_inout := p_out;        --   ERROR,   OUTPUT tidak boleh digunakan
        p_in := p_out            --   PARAH
END;
$$ LANGUAGE 'plpgsql';
Parameter output adalah parameter yang bernilai NULL, dan harus diisikan nilainya pada saat
eksekusi fungsi. Nilai akhir dari parameter adalah nilai yang di hasilkan(yang di RETURN) oleh fungsi
tersebut.

Oleh karena itu parameter output tidak boleh digunakan, karena bernilai NULL.




                                                                        8|S tored Proc edure
ILUSTRASI VARIABEL PARAMETER FUNGSI
  1. Fungsi yang menggunakan 1 parameter masukan IN dan parameter keluaran VOID (tidak ada
     parameter




     keluarnya)
  2. Fungsi yang menggunakan 1 parameter masukan IN dan 2 parameter keluaran




     OUT
  3. Fungsi yang menggunakan 2 parameter masukan IN, 1 parameter keluaran OUT dan 2
     parameter masuk keluar




     INOUT




                                                             9|S tored Proc edure
CONTROL FLOW : LOOP

LOOP 1
LOOP
      <loop_body>
      EXIT WHEN kondisi_keluar
END LOOP;

Contoh :
...
counter := 0;
loop
      insert into deret1(NILAI) values (counter);
      counter := counter + 2;
      EXIT WHEN counter > 100;
end loop;
...



LOOP 2
WHILE <condition> LOOP
      <loop_body>
END LOOP;

Contoh :
...
counter := 0;
WHILE counter<= 100 LOOP
      insert into deret1(NILAI) values (counter);
      counter := counter + 2;
end loop;
...



LOOP 3
FOR <variabel> IN <start> .. <FINISH> LOOP
      <loop_body>
END LOOP;

Contoh 1 :
...
counter := 0;
FOR counter IN 0 .. 100 LOOP
      insert into deret1(NILAI) values (counter);
end loop;
...
Fungsi ini akan memasukkan nilai 0, 1, 2, 3, 4, ..., 100 (bilangan real).


                                                                        10 | S t o r e d P r o c e d u r e
Catatan : variabel yang di pergunakan sebagai acuan LOOP FOR harus bertipe integer.

Contoh 2 :
...
counter := 0;
FOR counter IN 0 .. 100 BY 2 LOOP
      insert into deret1(NILAI) values (counter);
end loop;
...
Fungsi ini akan memasukkan nilai 0, 2, 4, ..., 100 (bilangan genap). Karena nilai variabel counter di
tambah 2 tiap iterasi.

Contoh 3 :
...
counter := 0;
FOR counter IN REVERSE 0 .. 100 BY 2 LOOP
      insert into deret1(NILAI) values (counter);
end loop;
...
Fungsi ini akan memasukkan nilai 100, 98, 96, ..., 0 (bilangan genap). Karena urutan LOOP di balik.




                                                                        11 | S t o r e d P r o c e d u r e
CONDITIONAL

IF-THEN
IF <kondisi> THEN <statement> END IF;

Contoh :
...
       if (counter > 100) then
             exit;
       end if;
...




IF - THEN - ELSE
IF <kondisi> THEN <statement>
ELSE <statement>
END IF;

Contoh :
...
IF posisi = 80 THEN komentar := „bagus‟
ELSE komentar := „biasa‟
END IF;
...




IF – THEN – ELSEIF – ELSE
IF <kondisi_1> THEN ...
ELSEIF <kondisi_2> THEN ... ...
ELSEIF <kondisi_3> THEN ... ... ...
ELSE ... ... ... ...
END IF;

Contoh :
...
IF number = 0 THEN
      result := „enol‟;
ELSIF number > 0 THEN
      result := „bilangan positif‟;
ELSIF number < 0 THEN
      result := „bilangan negatif‟;
ELSE
      -- hmm, satu-satunya kemungkinan lain adalah angka tersebut NULL
      result := „NULL‟;
END IF;
...




                                                  12 | S t o r e d P r o c e d u r e
CURSOR

MENDEKLARASIKAN CURSOR
DECLARE
curs1 refcursor;
curs2 CURSOR FOR SELECT nilai FROM deret1;
curs3 CURSOR (key integer) IS SELECT * FROM deret1 WHERE nilai = key;

ketiga variabel ini bertipe data refcursor, tetapi curs1 dapat digunakan untuk semua query,
sedangkan yang kedua sudah memiliki query, dan yang terakhir memiliki query yang ber parameter
(key akan digantikan dengan nilai bertipe integer saat cursor di open).

Catatan :

curs2 CURSOR FOR SELECT * FROM deret1;
dengan
curs2 CURSOR IS SELECT * FROM deret1;
memiliki fungsi yang sama


MEMBUKA CURSOR
Untuk curs2 diatas, perintah untuk membukanya :
         OPEN curs2;


Untuk curs3 diatas, perintah untuk membukanya :
         OPEN curs3(23);


Untuk curs1 diatas, perintah untuk membukanya :
         OPEN curs1 FOR SELECT * FROM mahasiswa;




MENGGUNAKAN CURSOR
Setelah cursor dibuka, nilainya dapat di manipulasi dengan perintah yang di deskripsikan disini :

Untuk curs2, curs3 dan curs4 diatas, perintah untuk menggunakannya adalah :

         FETCH curs2 INTO v_nilai;
         FECTH curs3 INTO v_nilai;
         FETCH curs1 INTO v_nilai;


Atau jika curs1 memiliki lebih dari satu kolom, anda dapat menggunakannya dengan cara :

         FETCH curs1 INTO v_nilai1, v_nilai2, v_nilai3;



Setelah digunakan sebaiknya cursor ditutup untuk menghemat memory yang digunakan


                                                                     13 | S t o r e d P r o c e d u r e
CLOSE <nama_cursor>;
Ex :
        CLOSE curs1;

Contoh 8 :
CREATE OR REPLACE FUNCTION isi_komentar1() RETURNS VOID AS
$$
DECLARE
v_nilai deret2.nilai%type;
v_komentar deret2.komentar%type;
c_nilai CURSOR IS SELECT nilai FROM deret2;
BEGIN
      OPEN c_nilai;
      LOOP
            FETCH c_nilai INTO v_nilai;
            EXIT WHEN NOT FOUND;

                  IF v_nilai>3 THEN
                        v_komentar := 'BAGUS';
                  ELSE
                        v_komentar := 'BIASA';
                  END IF;
                  UPDATE deret2 SET komentar = v_komentar WHERE nilai = v_nilai;

        END LOOP;
        CLOSE c_nilai;
END;
$$ LANGUAGE 'plpgsql';

Contoh 9 :
  (Dari Presentasi Bpk Yudi Wbs)
  Diketahui:
           Tabel JAWABAN (NIM char, NO_SOAL int, JAWAB char)
           Tabel KUNCI (NO_SOAL int, KUNCI char)
  Isilah tabel SKOR (NIM char,SKOR int) dengan aturan: jawaban benar 4 point, jawaban salah -1.

Tabel Jawaban :

CREATE TABLE jawaban (nim char(6), no_soal integer, jawaban char(1));
Dummy data :
INSERT INTO jawaban VALUES
-- MAHASISWA 1, NIM : 123456
('123456',1,'A'),('123456',2,'A'),('123456',3,'A'),('123456',4,'A'),('123456',5,'A'),
('123456',6,'A'),('123456',7,'A'),('123456',8,'A'),('123456',9,'A'),('123456',10,'A'),
-- MAHASISWA 2, NIM : 234567
('234567',1,'A'),('234567',2,'B'),('234567',3,'C'),('234567',4,'D'), ('234567',5,'B'),
('234567',6,'D'),('234567',7,'B'),('234567',8,'C'),('234567',9,'D'),('234567',10,'E'),
-- MAHASISWA 3, NIM : 345678
('345678',1,'A'), ('345678',2,'A'), ('345678',3,'C'), ('345678',4,'E'),('345678',5,'B'),
('345678',6,'D'),('345678',7,'E'),('345678',8,'A'),('345678',9,'D'),('345678',10,'A'),
-- MAHASISWA 4, NIM 999999
('999999',1,'B'), ('999999',2,'B'), ('999999',3,'D'), ('999999',4,'A'),('999999',5,'C'),
('999999',6,'A'),('999999',7,'C'),('999999',8,'B'),('999999',9,'A'),('999999',10,'A');



                                                                  14 | S t o r e d P r o c e d u r e
Tabel kunci :
CREATE TABLE kunci (no_soal integer, kunci char(1));
Dummy Data :
INSERT INTO kunci VALUES
(1,'A'), (2,'A'), (3,'C'), (4,'E'), (5,'B'), (6,'D'), (7,'E'), (8,'A'), (9,'D'), (10,'C');


Dengan Summary skor dari Dummy Data jawaban mahasiswa adalah seperti berikut :
Mahasiswa 1, NIM 123456 : benar (3), salah (7) = (4*3) – (1*7) = 5
Mahasiswa 2, NIM 234567 : benar(5), salah (5) = (4*5) – (1*5) =15
Mahasiswa 3, NIM 345678 : benar(9), salah(1) = (4*9) – (1*1) = 35
Mahasiswa 4, NIM 999999 : benar(0), salah(10) = (4*0) – (1*10) = -10

Tabel Skor :
CREATE TABLE skor (nim char(6), skor integer);

Prosedur :
CREATE OR REPLACE FUNCTION isi_skor() RETURNS VOID AS
$$
DECLARE
v_nim skor.nim%TYPE;
v_skor skor.skor%TYPE;
v_no_soal jawaban.no_soal%TYPE;
v_jawaban jawaban.jawaban%TYPE;
v_kunci kunci.kunci%TYPE;
c_mahasiswa CURSOR IS SELECT DISTINCT nim FROM jawaban;
c_jawaban CURSOR (v_nim_mhs jawaban.nim%TYPE)FOR SELECT no_soal, jawaban FROM jawaban WHERE
nim = v_nim_mhs;
c_kunci REFCURSOR;
BEGIN
        OPEN   c_mahasiswa;
        LOOP
               FETCH c_mahasiswa INTO v_nim;
               RAISE NOTICE 'nim : %', v_nim;
               EXIT WHEN NOT FOUND;
               v_skor := 0;
               OPEN c_jawaban(v_nim);
               LOOP
                       FETCH c_jawaban INTO v_no_soal,v_jawaban;
                       EXIT WHEN NOT FOUND;
                       RAISE INFO 'no soal : %, jawaban : %', v_no_soal, v_jawaban;
                       OPEN c_kunci FOR SELECT kunci FROM kunci WHERE no_soal = v_no_soal;
                       FETCH c_kunci INTO v_kunci;
                       RAISE INFO 'kunci : %', v_kunci;
                       CLOSE c_kunci;

                               IF v_jawaban <> v_kunci THEN
                                       RAISE INFO 'SALAH, %-1', v_skor;
                                       v_skor := v_skor-1;
                               ELSE
                                       RAISE INFO 'BENAR, %+4', v_skor;
                                       v_skor := v_skor + 4;
                               END IF;
                        RAISE INFO 'skor : %', v_skor;
                END LOOP;
                INSERT INTO skor VALUES (v_nim, v_skor);
                CLOSE c_jawaban;
        END LOOP;
        CLOSE c_mahasiswa;
END;
$$ LANGUAGE 'plpgsql';




                                                                15 | S t o r e d P r o c e d u r e
Contoh 10 :
  (Dari Presentasi Bpk Yudi Wbs)
  Tabel input:
  TRANS_HARIAN
          (TGL date, JUM_TRANS int,ID_CUST int)
  Buatlah SP untuk mengisi tabel output:
          TRANS_BULANAN
                   (THN int,BULAN int, JUM_TRANS int, ID_CUST int)
          TRANS_TAHUNAN
                   (TAHUN int, JUM_TRANS int, ID_CUST int)

Tabel Trans_Harian:

CREATE TABLE trans_harian (tgl timestamp, jum_trans integer, id_cust integer);
Dummy data :
INSERT INTO trans_harian VALUES
(to_timestamp('05 01 2000','DD MM YYYY'),12,1),(to_timestamp('06 01 2000','DD MM YYYY'),3,1),(to_timestamp('05 02 2000','DD
MM YYYY'),4,2),(to_timestamp('07 01 2000','DD MM YYYY'),9,3),(to_timestamp('12 04 2000','DD MM YYYY'),1,1),(to_timestamp('05
01 2000','DD MM YYYY'),15,2),(to_timestamp('05 09 2000','DD MM YYYY'),21,1),(to_timestamp('05 10 2000','DD MM
YYYY'),80,3),(to_timestamp('05 01 2001','DD MM YYYY'),8,1),(to_timestamp('05 02 2001','DD MM YYYY'),6,2),(to_timestamp('05 03
2001','DD MM YYYY'),9,3),(to_timestamp('05 04 2001','DD MM YYYY'),12,3),(to_timestamp('05 05 2001','DD MM
YYYY'),13,3),(to_timestamp('05 06 2001','DD MM YYYY'),80,1),(to_timestamp('05 07 2001','DD MM YYYY'),19,2),(to_timestamp('05
08 2001','DD MM YYYY'),67,1),(to_timestamp('05 09 2001','DD MM YYYY'),999,2),(to_timestamp('05 10 2001','DD MM
YYYY'),87,1),(to_timestamp('05 11 2001','DD MM YYYY'),90,2),(to_timestamp('05 12 2001','DD MM YYYY'),56,2),(to_timestamp('01
1 2002','DD MM YYYY'),76,1),(to_timestamp('15 1 2002','DD MM YYYY'),6,2),(to_timestamp('20 1 2002','DD MM
YYYY'),96,3),(to_timestamp('05 2 2002','DD MM YYYY'),45,1),(to_timestamp('17 2 2002','DD MM YYYY'),67,2),(to_timestamp('13 2
2002','DD MM YYYY'),23,3),(to_timestamp('25 2 2002','DD MM YYYY'),84,1),(to_timestamp('21 2 2002','DD MM
YYYY'),42,2),(to_timestamp('18 3 2002','DD MM YYYY'),45,3),(to_timestamp('12 3 2002','DD MM YYYY'),12,1),(to_timestamp('16 3
2002','DD MM YYYY'),67,2),(to_timestamp('19 3 2002','DD MM YYYY'),86,3),(to_timestamp('22 3 2002','DD MM
YYYY'),56,1),(to_timestamp('23 3 2002','DD MM YYYY'),43,2),(to_timestamp('24 3 2002','DD MM YYYY'),90,3),(to_timestamp('01 4
2002','DD MM YYYY'),75,1),(to_timestamp('02 4 2002','DD MM YYYY'),45,2),(to_timestamp('11 4 2002','DD MM
YYYY'),65,3),(to_timestamp('13 4 2002','DD MM YYYY'),57,1),(to_timestamp('14 5 2002','DD MM YYYY'),43,2),(to_timestamp('17 5
2002','DD MM YYYY'),93,3),(to_timestamp('28 5 2002','DD MM YYYY'),34,1),(to_timestamp('26 6 2002','DD MM
YYYY'),67,2),(to_timestamp('21 7 2002','DD MM YYYY'),32,3),(to_timestamp('22 7 2002','DD MM YYYY'),43,1),(to_timestamp('23 7
2002','DD MM YYYY'),56,2),(to_timestamp('24 7 2002','DD MM YYYY'),97,3),(to_timestamp('01 8 2002','DD MM
YYYY'),91,1),(to_timestamp('01 9 2002','DD MM YYYY'),23,2),(to_timestamp('05 12 2002','DD MM YYYY'),576,3);


Tabel Trans_bulanan
CREATE TABLE trans_bulanan(thn integer, bulan integer, jum_trans integer, id_cust integer);
Tabel Trans_tahunan
CREATE TABLE trans_tahunan(thn integer, jum_trans integer, id_cust integer);
Prosedur-Prosedur :

Cust_per_tahun
CREATE OR REPLACE FUNCTION cust_per_tahun (v_tahun INTEGER) RETURNS REFCURSOR AS
$$
DECLARE
v_curs_thn REFCURSOR;
BEGIN
OPEN v_curs_thn FOR SELECT DISTINCT id_cust FROM trans_harian WHERE EXTRACT (year
FROM tgl) = v_tahun;
RETURN (v_curs_thn);
END;
$$ LANGUAGE 'plpgsql';


Trans_thn_cust
CREATE OR REPLACE FUNCTION trans_thn_cust (v_tahun INTEGER, v_id_cust INTEGER)
RETURNS INTEGER AS
$$
DECLARE

                                                                                    16 | S t o r e d P r o c e d u r e
jmlh_trans INTEGER;

BEGIN
SELECT INTO jmlh_trans SUM(jum_trans) FROM trans_harian WHERE id_cust = v_id_cust
AND EXTRACT (YEAR FROM tgl) = v_tahun;
RETURN (jmlh_trans);

END;
$$ LANGUAGE 'plpgsql';


Trans_bln_cust
CREATE OR REPLACE FUNCTION trans_bln_cust (v_tahun INTEGER, v_bulan INTEGER,
v_id_cust INTEGER) RETURNS INTEGER AS
$$
DECLARE
jmlh_trans INTEGER;
BEGIN
SELECT INTO jmlh_trans SUM(jum_trans) FROM trans_harian WHERE id_cust = v_id_cust
AND EXTRACT (MONTH FROM tgl) = v_bulan AND EXTRACT (YEAR FROM tgl) = v_tahun;
RETURN (jmlh_trans);
END;
$$ LANGUAGE 'plpgsql';


Isi_summary_trans jalankan fungsi ini untuk mengisi tabel trans bulanan dan tahunan.
CREATE OR REPLACE FUNCTION isi_summary_trans() RETURNS VOID AS
$$
DECLARE
v_tahun INTEGER;
v_bulan INTEGER;
v_id_cust INTEGER;
v_trans_cust_thn INTEGER;
v_trans_cust_bln INTEGER;

c_tahun CURSOR IS SELECT DISTINCT EXTRACT (YEAR FROM tgl) FROM trans_harian;
c_cust_thn REFCURSOR;

BEGIN
        OPEN   c_tahun;
        LOOP
               FETCH c_tahun INTO v_tahun;
               EXIT WHEN NOT FOUND;
               c_cust_thn := cust_per_tahun(v_tahun);
               LOOP
                       FETCH c_cust_thn INTO v_id_cust;
                       EXIT WHEN NOT FOUND;
                       v_trans_cust_thn := trans_thn_cust (v_tahun,v_id_cust);
                       INSERT INTO trans_tahunan VALUES (v_tahun,v_trans_cust_thn,v_id_cust);
                       v_bulan := 1;
                       FOR v_bulan IN 1..12 LOOP
                               v_trans_cust_bln := trans_bln_cust(v_tahun,v_bulan,v_id_cust);
                               INSERT INTO trans_bulanan
VALUES(v_tahun,v_bulan,v_trans_cust_bln,v_id_cust);
                       END LOOP;
               END LOOP;
               CLOSE c_cust_thn;
       END LOOP;
       CLOSE c_tahun;
END;
$$ LANGUAGE 'plpgsql';




                                                                 17 | S t o r e d P r o c e d u r e
Tahun/Customer        2000              2001                     2002
      Bulan       1     2    3     1      2     3         1        2        3
        1        15    15    9     8                     76        6        96
        2               4                6              129      109        23
        3                                       9        68      110       221
        4                                      12       132       45        65
        5                                      13        34       43        93
        6                         80                              67
        7                                19              43       56       129
        8                         67                     91
        9        21                     999                       23
       10                    80   87
       11                                90
       12                                56                                576
Total            37   19     89   242   1170   34       573       459     1203




                                               18 | S t o r e d P r o c e d u r e
<(Pengayaan)>
DEKLARASI VARIABEL
 nama_variabel [ CONSTANT ] type_data [ NOT NULL ] [ { DEFAULT | := } nilai_awal ];

CONSTANT        : nilai variabel tidak dapat di ubah.
NOT NULL        : nilai variabel tidak boleh bernilai null.
DEFAULT         :
       Nilai default selalu di evaluasi tiap suatu block di masuki. Sebagai contoh, menggunakan
now() sebagai nilai default akan membuat variabel memiliki nilai waktu saat fungsi tersebut di
eksekusi. Jika menggunakan := now(), akan membuat variabel memiliki nilai waktu saat fungsi
tersebut di compile.
Contoh :
quantity integer DEFAULT 32;
url varchar := „http://mysite.com‟;
user_id CONSTANT integer := 10;


ALIAS UNTUK PARAMETER FUNGSI
Parameter yang di kirimkan ke fungsi secara default di identifikasikan dengan $1, $2, etc.
Untuk memudahkan pembacaan fungsi, nama alias dapat di pergunakan(ini yang di pergunakan
sebagai contoh-contoh diatas). Namun parameter yang di beri nama alias masih tetap dapat
direferensikan dengan nama default $1, $2, ect.
        Ada dua cara untuk membuat alias. Cara yang sering digunakan adalah dengan memberi
nama alias pada pembuatan fungsi. Contoh :

CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
      BEGIN
      RETURN subtotal * 0.06;
      END;
$$ LANGUAGE plpgsql;

Cara kedua, adalah satu-satunya cara yang di perbolehkan pada versi sebelum 8.0 :

CREATE FUNCTION sales_tax(real) RETURNS real AS $$
      DECLARE
      subtotal ALIAS FOR $1;
      BEGIN
      RETURN subtotal * 0.06;
      END;
$$ LANGUAGE plpgsql;


Alias untuk Parameter Output
Saat fungsi PL/pgSQL mendeklarasikan parameter output, parameter output tersebut juga
diidentifikasikan dengan $n, paramaeter output ini dapat juga di beri nama alias sama seperti
parameter input. Parameter output adalah parameter yang bernilai NULL, dan harus diisikan
nilainya pada saat eksekusi fungsi. Nilai akhir dari parameter adalah nilai yang di hasilkan(yang di



                                                                      19 | S t o r e d P r o c e d u r e
RETURN) oleh fungsi tersebut. Bentuk lain dari output parameter RETURNS pada deklarasi fungsi
adalah dengan mendefinisikan OUT pada parameter fungsi. Contoh :
CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
      BEGIN
      tax := subtotal * 0.06;
      END;
$$ LANGUAGE plpgsql;

Dapat dilihat pada fungsi diatas, tidak ada pendeklarasian RETURN, anda dapat mendeklarasikan
RETURN, namun hal tersebut akan menghasilkan redudansi pada badan fungsi.
Parameter output seperti ini akan sangat berguna saat fungsi menghasilkan lebih dari satu variabel
hasil. Contoh :
CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS
$$
      BEGIN
      sum := x + y;
      prod := x * y;
      END;
$$ LANGUAGE plpgsql;




VARIABEL BERTIPE DATA COMPOSITE (CAMPURAN)
Pada lingkungan programming, tipe data campuran seringkali digunakan untuk menangani berbagai
masalah seperti Lingked List, Stack, Queue, Tree, Graph dll.

Contoh : Tipe data titik dengan dua variabel (x, y)

PADA LINGKUNGAN PEMROGRAMAN JAVA
Deklarasi variabel ini dapat di lakukan dengan cara membuat kelas baru yang dinamakan kelas titik

public class titik
{
       public int x = 0;
       public int y = 0;
}
Anda dapat menggunakan kelas ini dengan membuat objek baru dengan properties kelas, misalkan
anda ingin menggambar garis dari titik A ke titik B, maka anda harus membuat objek titik A dan
objek titik B.
public class garis
{
       Public static void main (String[] args)
       {
               public titik A = new titik();
               public titik B = new titik();
                      /* gambar garis dari titik (4, 5) dan (9, 8) */
                      A.x = 4; A.y = 5;
                      B.x = 9; B.y = 8;
               System.out.println(“ garis dari (“+A.x+”,”+A.y”) ke (“+B.x+”,”+B.y”)”);
       }
}




                                                                   20 | S t o r e d P r o c e d u r e
PADA LINGKUNGAN PEMROGRAMAN C/C++
Deklarasi variabel dilakukan dengan cara membuat tipe data baru, yang lalu di pergunakan dalam
badan fungsi.
#include <stdio.h>
main()
{
       struct titik { int x; int y; }
       titik A;
       titik B;

       /* gambar garis dari titik (4, 5) dan (9, 8) */
              A.x = 4; A.y = 5;
              B.x = 9; B.y = 8;
       printf(“ garis dari (%d,%d) ke (%d,%d)”, A.x, A.y, B.x, B.y);
}



PADA LINGKUNGAN POSTGRESQL
Pada contoh-contoh sebelumnya fungsi-fungsi hanya menggunakan tipe data bawaan dari
postgreSQL, sebenarnya kita dapat membuat tipe data sendiri dengan cara

CREATE TYPE <nama_tipe> AS (
       <nama_variabel> <tipe_data_variabel>
);


Contoh :
CREATE TYPE titik AS
(
       x integer,
       y integer
);

Tipe data baru ini dapat anda pergunakan untuk berbagai keperluan, misalkan membuat tabel
dengan kolom dengan tipe data ini, maupun menggunakan tipe data ini pada fungsi.
Contoh :
CREATE TABEL garis (a titik, b titik);

INSERT INTO garis VALUES ((2,3),(4,5));
INSERT INTO garis VALUES ((3,9),(8,5));
INSERT INTO garis VALUES ((2,6),(4,6));

SELECT (a).x FROM garis;
-- atau jika anda menggunakan nama tabel untuk operasi multi tabel
SELECT (garis.a).x FROM garis;
SELECT * FROM garis WHERE (a).x = 2;
SELECT * FROM garis WHERE (b).y = 5;

-- pada operasi update, kita tidak boleh menggunakan tanda kurung setelah SET
UPDATE garis SET (b).y = 99 WHERE (b).y = 5;   -- ERROR
UPDATE garis SET b.y = 99 WHERE (b).y = 5;
-- tetapi tanda kurung harus digunakan saat mereferensi kolom yang sama pada
-- ekspresi di sebelah kanan tanda sama dengan
UPDATE garis SET a.x = (a).x + 1 WHERE (a).x = 3;
-- kita juga dapat menggunakan sub-field ini sebagai sasaran operasi insert
INSERT INTO garis (a.x, b.y) VALUES (99, 55);

                                                                 21 | S t o r e d P r o c e d u r e
Seperti telah disebutkan diatas, kita juga dapat membuat fungsi dengan tipe data campuran ini.
CREATE FUNCTION masukkan_titik_a_ke_garis (v_a_x integer, v_a_y integer) RETURNS VOID AS
$$
BEGIN
       INSERT INTO garis (a.x, a.y) VALUES (v_a_x, v_a_y);
END;
$$ LANGUAGE 'plpgsql';


Anda dapat mengeksekusi fungsi diatas dengan cara :
select masukkan_titik_a_ke_garis(25,67);

dengan tipe data campuran ini, anda diberikan kebebasan dalam pemrograman dengan hanya
mengeluarkan satu variabel yang mengandung isi lebih dari satu variabel.




                                                                  22 | S t o r e d P r o c e d u r e

Más contenido relacionado

La actualidad más candente

ERD Sistem Informasi Pemesanan Tiket Bioskop Online
ERD Sistem Informasi Pemesanan Tiket Bioskop OnlineERD Sistem Informasi Pemesanan Tiket Bioskop Online
ERD Sistem Informasi Pemesanan Tiket Bioskop OnlineLucha Kamala Putri
 
6 Algoritma Pengurutan Data
6 Algoritma Pengurutan Data6 Algoritma Pengurutan Data
6 Algoritma Pengurutan DataSimon Patabang
 
Langkah dalam membuat cristal report dalam vb
Langkah dalam membuat cristal report dalam vbLangkah dalam membuat cristal report dalam vb
Langkah dalam membuat cristal report dalam vbwnofrizal
 
Kesimpulan Makalah dan Makalah Gojek
Kesimpulan Makalah dan Makalah GojekKesimpulan Makalah dan Makalah Gojek
Kesimpulan Makalah dan Makalah GojekSultan Habib
 
Biaya yang Diperlukan Dalam Proses Pembuatan Batik
Biaya yang Diperlukan Dalam Proses Pembuatan BatikBiaya yang Diperlukan Dalam Proses Pembuatan Batik
Biaya yang Diperlukan Dalam Proses Pembuatan BatikZufar Asyraf Al
 
Proposal bisnis startup rumah dana
Proposal bisnis startup rumah danaProposal bisnis startup rumah dana
Proposal bisnis startup rumah danaAulya Yarzuki
 
My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"
My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"
My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"Cindy_Jenyffer
 
Diagram erd restaurant
Diagram erd restaurantDiagram erd restaurant
Diagram erd restaurantRistaMeytasari
 
Jaringanhebb
JaringanhebbJaringanhebb
JaringanhebbSan Toso
 
Algoritma dan Struktur Data - Struktur Data
Algoritma dan Struktur Data - Struktur DataAlgoritma dan Struktur Data - Struktur Data
Algoritma dan Struktur Data - Struktur DataKuliahKita
 
Teori pendekatan kardinal ordinal
Teori pendekatan kardinal ordinalTeori pendekatan kardinal ordinal
Teori pendekatan kardinal ordinalagusmulyana41
 
Metode Penyusutan
Metode PenyusutanMetode Penyusutan
Metode Penyusutanmsahuleka
 
Pelatihan menggunakan analisis sem pls dengan warp pls 60
Pelatihan menggunakan analisis sem pls dengan warp pls 60 Pelatihan menggunakan analisis sem pls dengan warp pls 60
Pelatihan menggunakan analisis sem pls dengan warp pls 60 mnurutomo
 

La actualidad más candente (20)

Graph-Struktur Data.pdf
Graph-Struktur Data.pdfGraph-Struktur Data.pdf
Graph-Struktur Data.pdf
 
Jaringan hebb
Jaringan hebbJaringan hebb
Jaringan hebb
 
ERD Sistem Informasi Pemesanan Tiket Bioskop Online
ERD Sistem Informasi Pemesanan Tiket Bioskop OnlineERD Sistem Informasi Pemesanan Tiket Bioskop Online
ERD Sistem Informasi Pemesanan Tiket Bioskop Online
 
6 Algoritma Pengurutan Data
6 Algoritma Pengurutan Data6 Algoritma Pengurutan Data
6 Algoritma Pengurutan Data
 
Langkah dalam membuat cristal report dalam vb
Langkah dalam membuat cristal report dalam vbLangkah dalam membuat cristal report dalam vb
Langkah dalam membuat cristal report dalam vb
 
Kesimpulan Makalah dan Makalah Gojek
Kesimpulan Makalah dan Makalah GojekKesimpulan Makalah dan Makalah Gojek
Kesimpulan Makalah dan Makalah Gojek
 
Biaya yang Diperlukan Dalam Proses Pembuatan Batik
Biaya yang Diperlukan Dalam Proses Pembuatan BatikBiaya yang Diperlukan Dalam Proses Pembuatan Batik
Biaya yang Diperlukan Dalam Proses Pembuatan Batik
 
Array dan Pointer
Array dan PointerArray dan Pointer
Array dan Pointer
 
Proposal bisnis startup rumah dana
Proposal bisnis startup rumah danaProposal bisnis startup rumah dana
Proposal bisnis startup rumah dana
 
My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"
My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"
My Project "Sistem Database (MySQL) : Pemesanan Makanan dan Minuman Online"
 
Diagram erd restaurant
Diagram erd restaurantDiagram erd restaurant
Diagram erd restaurant
 
Jaringanhebb
JaringanhebbJaringanhebb
Jaringanhebb
 
Materi 7
Materi 7Materi 7
Materi 7
 
Proposal Perkedel
Proposal PerkedelProposal Perkedel
Proposal Perkedel
 
Algoritma dan Struktur Data - Struktur Data
Algoritma dan Struktur Data - Struktur DataAlgoritma dan Struktur Data - Struktur Data
Algoritma dan Struktur Data - Struktur Data
 
Teori pendekatan kardinal ordinal
Teori pendekatan kardinal ordinalTeori pendekatan kardinal ordinal
Teori pendekatan kardinal ordinal
 
Resume praktikum 6 stack
Resume praktikum 6 stackResume praktikum 6 stack
Resume praktikum 6 stack
 
Metode Penyusutan
Metode PenyusutanMetode Penyusutan
Metode Penyusutan
 
Structure and pointer
Structure and pointerStructure and pointer
Structure and pointer
 
Pelatihan menggunakan analisis sem pls dengan warp pls 60
Pelatihan menggunakan analisis sem pls dengan warp pls 60 Pelatihan menggunakan analisis sem pls dengan warp pls 60
Pelatihan menggunakan analisis sem pls dengan warp pls 60
 

Similar a PostgreSQL Stored-procedure

Similar a PostgreSQL Stored-procedure (20)

Tipe data
Tipe dataTipe data
Tipe data
 
Modul Pascal Mengenal Flowchart
Modul Pascal Mengenal FlowchartModul Pascal Mengenal Flowchart
Modul Pascal Mengenal Flowchart
 
Algoritma flowchart
Algoritma flowchartAlgoritma flowchart
Algoritma flowchart
 
Modul pascal
Modul pascalModul pascal
Modul pascal
 
Modul pascal
Modul pascalModul pascal
Modul pascal
 
Modul Pascal.pdf
Modul Pascal.pdfModul Pascal.pdf
Modul Pascal.pdf
 
Modul pascal
Modul pascalModul pascal
Modul pascal
 
modul algoritma Bab 5
modul algoritma Bab 5modul algoritma Bab 5
modul algoritma Bab 5
 
Pertemuan II Function
Pertemuan II FunctionPertemuan II Function
Pertemuan II Function
 
Function
FunctionFunction
Function
 
Function
FunctionFunction
Function
 
Algoritma pemrograman 14
Algoritma pemrograman 14Algoritma pemrograman 14
Algoritma pemrograman 14
 
struktur pemrograman pascal - MATA KULIAH STRUKTUR DATA
struktur pemrograman pascal - MATA KULIAH STRUKTUR DATAstruktur pemrograman pascal - MATA KULIAH STRUKTUR DATA
struktur pemrograman pascal - MATA KULIAH STRUKTUR DATA
 
Struktur pemrograman pascal
Struktur pemrograman pascalStruktur pemrograman pascal
Struktur pemrograman pascal
 
Fungsi
FungsiFungsi
Fungsi
 
Dasar Pemrograman materi kuliah
Dasar Pemrograman materi kuliahDasar Pemrograman materi kuliah
Dasar Pemrograman materi kuliah
 
Alpro referensi
Alpro referensiAlpro referensi
Alpro referensi
 
listiati univ bung hata (1110013211051) Bahasa pemrograman pascal
listiati univ bung hata (1110013211051) Bahasa pemrograman pascallistiati univ bung hata (1110013211051) Bahasa pemrograman pascal
listiati univ bung hata (1110013211051) Bahasa pemrograman pascal
 
Javascript function
Javascript   functionJavascript   function
Javascript function
 
Fungsi dasar rumus microsoft excel
Fungsi dasar rumus microsoft excelFungsi dasar rumus microsoft excel
Fungsi dasar rumus microsoft excel
 

Más de Ammar Shadiq

Statement of Accomplisment from Online Machine Learning Class
Statement of Accomplisment from Online Machine Learning ClassStatement of Accomplisment from Online Machine Learning Class
Statement of Accomplisment from Online Machine Learning ClassAmmar Shadiq
 
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa IndonesiaMendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa IndonesiaAmmar Shadiq
 
PostgreSQL Transaksi
PostgreSQL TransaksiPostgreSQL Transaksi
PostgreSQL TransaksiAmmar Shadiq
 
Pengenalan konsep dan komponen Oracle database recovery
Pengenalan konsep dan komponen Oracle database recoveryPengenalan konsep dan komponen Oracle database recovery
Pengenalan konsep dan komponen Oracle database recoveryAmmar Shadiq
 
Pelatihan Java - Number & String
Pelatihan Java - Number & StringPelatihan Java - Number & String
Pelatihan Java - Number & StringAmmar Shadiq
 

Más de Ammar Shadiq (7)

Statement of Accomplisment from Online Machine Learning Class
Statement of Accomplisment from Online Machine Learning ClassStatement of Accomplisment from Online Machine Learning Class
Statement of Accomplisment from Online Machine Learning Class
 
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa IndonesiaMendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
 
PostgreSQL Transaksi
PostgreSQL TransaksiPostgreSQL Transaksi
PostgreSQL Transaksi
 
Pengenalan konsep dan komponen Oracle database recovery
Pengenalan konsep dan komponen Oracle database recoveryPengenalan konsep dan komponen Oracle database recovery
Pengenalan konsep dan komponen Oracle database recovery
 
Oracle transaksi
Oracle transaksiOracle transaksi
Oracle transaksi
 
Java numbers
Java numbersJava numbers
Java numbers
 
Pelatihan Java - Number & String
Pelatihan Java - Number & StringPelatihan Java - Number & String
Pelatihan Java - Number & String
 

PostgreSQL Stored-procedure

  • 1. Stored Procedure  Function (pada PostgreSQL) M. Ammar Shadiq Ilmu Komputer  Universitas Pendidikan Indonesia, Bandung 5 Mei 2008 Pertama-tama anda harus menginisiasikan procedural language (bahasa prosedural) pada postgreSQL yang dinamakan PL/pgsql, perintahnya : CREATE LANGUAGE plpgsql; TABEL YANG DIGUNAKAN : DERET1 : (NILAI INTEGER) CREATE TABLE deret1 (nilai integer); DERET2 : (NILAI INTEGER, KOMENTAR CHARACTER(8)) CREATE TABLE deret2 (nilai integer, komentar character(8)); Dengan Dummy Data : (1), (2), (3), (4),(5) INSERT INTO deret2 (nilai) VALUES (1),(2),(3),(4),(5); ACCOUNT : (NAMA CHARACTER(50), SALDO INTEGER, CABANG CHARACT ER(50)) CREATE TABLE account (nama character(50),saldo integer,cabang character(50); Dengan Dummy Data : (shadiq, Rp. 100.000, Bogor), (Alice, Rp. 1.000.000, Bogor), (Bob, Rp. 700.000, Bandung), (Wally, Rp. 500.000, Bandung) INSERT INTO account VALUES ('shadiq',100000,'Bogor'), ('Alice',1000000,'Bogor'), ('Bob',700000,'Bandung'), ('Wally',500000,'Bandung'); 1|S tored Proc edure
  • 2. PENDAHULUAN Contoh 1 : Fungsi untuk mengisi field nim pada tabel deret1 dengan nilai deret 0, 2, 4, ... , 100. CREATE OR REPLACE FUNCTION isi_deret1() RETURNS void AS $$ DECLARE counter integer; BEGIN counter := 0; loop insert into deret1(nilai) values (counter); counter := counter + 2; if (counter > 100) then exit; end if; end loop; return; END; $$ LANGUAGE 'plpgsql'; Eksekusi fungsi diatas : SELECT isi_deret1(); isi_deret1 --------- (1 row) Cek isi tabel deret1 yang sudah di modifikasi : SELECT * FROM deret1; Untuk melihat fungsi yang ada pada PostgreSQL anda dapat menuliskan perintah berikut : Melihat semua fungsi df Melihat fungsi tertentu df <nama_fungsi> Melihat isi fungsi df+ <nama_fungsi> 2|S tored Proc edure
  • 3. STRUKTUR FUNGSI PADA PL/PGSQL CREATE [OR REPLACE] FUNCTION nama_fungsi ( [ argtype [, ...] ] ) RETURNS return_type AS $$definition$$ LANGUAGE langname [ WITH ( attribute [, ...] ) ] MENGHAPUS FUNGSI DROP FUNCTION nama_fungsi(paramater[, parameter[, parameter ... ); Ex : DROP FUNCTION isi_deret11(); BADAN FUNGSI DECLARE /* deklarasi variabel, type dan subprogram lokal */ BEGIN /* prosedural dan SQL masuk disini */ / blok ini yang wajib */ END; DEKLARASI VARIABEL : Contoh : DECLARE v_counter INTEGER; v_nim CHAR(5); v_nama VARCHAR(2); v_nilai NUMBER; v_nim_2 mahasiswa.nim%TYPE /* tipe variabel mengikuti tipe field mahasiswa.nim */ mengapa menggunakan huruf depan v_? Supaya tidak bentrok dengan nama field. Contoh : INSERT INTO mahasiswa (nim, nama) VALUES (v_nim, v_nama); Nilai variabel juga dapat diinisiasikan saat pembuatannya. Contoh : v_nilai_minimum INTEGER := 30; Deklarasi Variabel pada Pembuatan Fungsi : Pendeklarasian variabel dapat juga dilakukan pada pembuatan fungsi, dengan konsekuensi varibel tersebut HARUS menjadi parameter input atau output. 3|S tored Proc edure
  • 4. Contoh 2 : Fungsi untuk mengisi field nim pada tabel deret1 dengan nilai deret 0 s/d nilai yang di tentukan dengan penambahan nilai +2 tiap iterasi. CREATE OR REPLACE FUNCTION isi_deret2(sampai_dengan integer) RETURNS void AS $$ DECLARE counter integer; BEGIN counter := 0; loop insert into deret1(nilai) values (counter); counter := counter + 2; if (counter>sampai_dengan) then exit; end if; end loop; return; END; $$ LANGUAGE 'plpgsql'; Pengeksekusian dilakukan dengan memasukkan parameter. SELECT isi_deret2(60); isi_deret2 --------- (1 row) Fungsi diatas akan memasukkan nilai 0, 2, 4, ..., 60 pada tabel deret1. Untuk menghapus fungsi dengan parameter masukan menggunakan perintah : DROP FUNCTION isi_deret2(integer); JENIS-JENIS VARIABEL PARAMETER FUNGSI. Ada tiga jenis parameter : IN : variabel input (default) OUT : variabel output INOUT : variabel input dan output Jika anda memperhatikan contoh-contoh fungsi diatas, pada waktu pendeklarasian fungsi ada parameter output yang ditandakan dengan RETURNS tipe_data. CREATE OR REPLACE FUNCTION isi_deret2(sampai_dengan integer) RETURNS void AS $$.......... 4|S tored Proc edure
  • 5. Pada contoh diatas karena fungsi tersebut tidak menghasilkan suatu nilai, maka parameter outputnya diisikan dengan tipe data VOID*. * Fungsi dengan parameter output void artinya tidak menghasilkan suatu nilai (tidak mengembalikan nilai) atau biasa disebut fungsi kosong. void : kekosongan, kehampaan (Kamus Inggris-Indonesia, John M. Echoles) Untuk lebih jelasnya, perhatikan contoh-contoh fungsi dibawah ini : Contoh 3 : CREATE FUNCTION contoh_parameter_1 (IN sampai_dengan integer) RETURNS void AS $$ DECLARE counter integer; BEGIN counter := 0; loop insert into deret1(nilai) values (counter); counter := counter + 2; if (counter>sampai_dengan) then exit; end if; end loop; return; END; $$ LANGUAGE 'plpgsql'; Fungsi ini sama dengan fungsi isi_deret2(integer) namun dengan penulisan yang berbeda. Karena sebenarnya IN adalah parameter default, sebenarnya tidak perlu di tuliskan, hal ini dimaksudkan agar dapat dimengerti. Contoh 4 : CREATE FUNCTION contoh_parameter_2 (IN sampai_dengan integer) RETURNS integer AS $$ DECLARE counter integer; BEGIN counter := 0; loop insert into deret1(nilai) values (counter); counter := counter + 2; if (counter>sampai_dengan) then exit; end if; end loop; RETURN counter; END; $$ LANGUAGE 'plpgsql'; Fungsi ini memberi nilai keluaran yaitu counter dengan tipe data integer. Saat ada nilai keluaran, konsekwensinya harus ada deklarasi RETURN yang menentukan nilai apa yang di keluarkan. 5|S tored Proc edure
  • 6. Contoh 5 : CREATE FUNCTION contoh_parameter_3 (IN sampai_dengan integer, OUT keluaran_sd integer) AS $$ DECLARE counter integer; BEGIN counter := 0; loop insert into deret1(nilai) values (counter); counter := counter + 2; if (counter>sampai_dengan) then exit; end if; end loop; keluaran_sd := counter; END; $$ LANGUAGE 'plpgsql'; Fungsi ini sama dengan fungsi contoh_parameter_2, namun tanpa deklarasi RETURNS pada awal deklarasi fungsi, juga tanpa deklarasi RETURN pada badan fungsi. Sebagai ganti RETURN, digunakan pengisian nilai variabel keluaran_sd dengan nilai variabel counter. Kita tetap dapat menggunakan statement RETURN pada badan fungsi, namun hal ini akan menyebabkan redudansi. Pilih salah satu saja. Catatan : perhatikan perbedaan RETURN pada badan fungsi dan RETURNS pada deklarasi fungsi. Dengan fungsi seperti ini, pemanggilannya dilakukan dengan hanya memasukkan nilai variabel input saja. SELECT contoh_parameter_3(60); contoh_parameter_3 ------------------ 62 (1 row) Pertanyaan : Kenapa hasil yang dikeluarkan 62 ? Jawaban : perhatikan bahwa fungsi diatas melakukan proses tiap iterasi dengan membandingkan variabel counter. Saat iterasi sebelum terakhir (misal 60) fungsi membandingkan jika variabel counter > 60, karena nilai variabel counter belum melebihi 60 (tetapi sama dengan) maka iterasi dilakukan sekali lagi dan nilai variabel counter bertambah menjadi 62. Saat fungsi melakukan perbandingan kembali (counter > 60 [62>60]), maka kondisi tidak terpenuhi, tetapi nilai variabel counter adalah 62. Oleh karena itu hasil yang dikeluarkan adalah 62 bukan 60. Contoh 6 : Fungsi yang menghasilkan dua keluaran : CREATE FUNCTION contoh_parameter_4 (IN sampai_dengan integer, OUT keluaran_sd integer, OUT banyaknya_data integer) AS $$ DECLARE counter1 integer; counter2 integer; BEGIN counter1 := 0; 6|S tored Proc edure
  • 7. counter2 := 0; loop insert into deret1(nilai) values (counter1); counter1 := counter1 + 2; -- memasukkan nilai genap counter2 := counter2 + 1; -- menghitung banyaknya iterasi if (counter1>sampai_dengan) then exit; end if; end loop; keluaran_sd := counter1; banyaknya_data := counter2; END; $$ LANGUAGE 'plpgsql'; Jika anda mengeksekusi fungsi ini dengan Variabel masukan sampai_dengan = 60, maka nilai variabel keluarannya adalah keluaran_sd = 62, dan variabel banyaknya_data = 31 (0...60). SELECT contoh_parameter_4(60); contoh_parameter_4 ------------------ (62,31) (1 row) Contoh 7 : CREATE FUNCTION contoh_parameter_5 (INOUT sampai_dengan integer) AS $$ DECLARE counter integer; BEGIN counter := 0; loop insert into deret1(nilai) values (counter); counter := counter + 2; if (counter>sampai_dengan) then exit; end if; end loop; sampai_dengan := counter; END; $$ LANGUAGE 'plpgsql'; Dapat di perhatikan pada fungsi diatas, variabel input dan outputnya sama yaitu variabel sampai_dengan. SELECT contoh_parameter_5(60); contoh_parameter_5 ------------------ 62 (1 row) 7|S tored Proc edure
  • 8. BATASAN-BATASAN Variabel input : tidak dapat diubah Variabel output : tidak dapat di jadikan nilai referensi pada variabel lain. Contoh : CREATE FUNCTION contoh_parameter_salah (IN p_in integer, OUT p_out integer, INOUT p_inout integer) AS $$ DECLARE local integer; BEGIN local := p_in; local := p_inout; p_out := p_in; p_out := local p_out := 5; p_inout := p_in; p_inout := local; p_inout := 5; p_in := 5; -- ERROR, INPUT tidak boleh diisi p_in := local; -- ERROR, INPUT tidak boleh diisi p_in := p_inout; -- ERROR, INPUT tidak boleh diisi local := p_out; -- ERROR, OUTPUT tidak boleh digunakan p_inout := p_out; -- ERROR, OUTPUT tidak boleh digunakan p_in := p_out -- PARAH END; $$ LANGUAGE 'plpgsql'; Parameter output adalah parameter yang bernilai NULL, dan harus diisikan nilainya pada saat eksekusi fungsi. Nilai akhir dari parameter adalah nilai yang di hasilkan(yang di RETURN) oleh fungsi tersebut. Oleh karena itu parameter output tidak boleh digunakan, karena bernilai NULL. 8|S tored Proc edure
  • 9. ILUSTRASI VARIABEL PARAMETER FUNGSI 1. Fungsi yang menggunakan 1 parameter masukan IN dan parameter keluaran VOID (tidak ada parameter keluarnya) 2. Fungsi yang menggunakan 1 parameter masukan IN dan 2 parameter keluaran OUT 3. Fungsi yang menggunakan 2 parameter masukan IN, 1 parameter keluaran OUT dan 2 parameter masuk keluar INOUT 9|S tored Proc edure
  • 10. CONTROL FLOW : LOOP LOOP 1 LOOP <loop_body> EXIT WHEN kondisi_keluar END LOOP; Contoh : ... counter := 0; loop insert into deret1(NILAI) values (counter); counter := counter + 2; EXIT WHEN counter > 100; end loop; ... LOOP 2 WHILE <condition> LOOP <loop_body> END LOOP; Contoh : ... counter := 0; WHILE counter<= 100 LOOP insert into deret1(NILAI) values (counter); counter := counter + 2; end loop; ... LOOP 3 FOR <variabel> IN <start> .. <FINISH> LOOP <loop_body> END LOOP; Contoh 1 : ... counter := 0; FOR counter IN 0 .. 100 LOOP insert into deret1(NILAI) values (counter); end loop; ... Fungsi ini akan memasukkan nilai 0, 1, 2, 3, 4, ..., 100 (bilangan real). 10 | S t o r e d P r o c e d u r e
  • 11. Catatan : variabel yang di pergunakan sebagai acuan LOOP FOR harus bertipe integer. Contoh 2 : ... counter := 0; FOR counter IN 0 .. 100 BY 2 LOOP insert into deret1(NILAI) values (counter); end loop; ... Fungsi ini akan memasukkan nilai 0, 2, 4, ..., 100 (bilangan genap). Karena nilai variabel counter di tambah 2 tiap iterasi. Contoh 3 : ... counter := 0; FOR counter IN REVERSE 0 .. 100 BY 2 LOOP insert into deret1(NILAI) values (counter); end loop; ... Fungsi ini akan memasukkan nilai 100, 98, 96, ..., 0 (bilangan genap). Karena urutan LOOP di balik. 11 | S t o r e d P r o c e d u r e
  • 12. CONDITIONAL IF-THEN IF <kondisi> THEN <statement> END IF; Contoh : ... if (counter > 100) then exit; end if; ... IF - THEN - ELSE IF <kondisi> THEN <statement> ELSE <statement> END IF; Contoh : ... IF posisi = 80 THEN komentar := „bagus‟ ELSE komentar := „biasa‟ END IF; ... IF – THEN – ELSEIF – ELSE IF <kondisi_1> THEN ... ELSEIF <kondisi_2> THEN ... ... ELSEIF <kondisi_3> THEN ... ... ... ELSE ... ... ... ... END IF; Contoh : ... IF number = 0 THEN result := „enol‟; ELSIF number > 0 THEN result := „bilangan positif‟; ELSIF number < 0 THEN result := „bilangan negatif‟; ELSE -- hmm, satu-satunya kemungkinan lain adalah angka tersebut NULL result := „NULL‟; END IF; ... 12 | S t o r e d P r o c e d u r e
  • 13. CURSOR MENDEKLARASIKAN CURSOR DECLARE curs1 refcursor; curs2 CURSOR FOR SELECT nilai FROM deret1; curs3 CURSOR (key integer) IS SELECT * FROM deret1 WHERE nilai = key; ketiga variabel ini bertipe data refcursor, tetapi curs1 dapat digunakan untuk semua query, sedangkan yang kedua sudah memiliki query, dan yang terakhir memiliki query yang ber parameter (key akan digantikan dengan nilai bertipe integer saat cursor di open). Catatan : curs2 CURSOR FOR SELECT * FROM deret1; dengan curs2 CURSOR IS SELECT * FROM deret1; memiliki fungsi yang sama MEMBUKA CURSOR Untuk curs2 diatas, perintah untuk membukanya : OPEN curs2; Untuk curs3 diatas, perintah untuk membukanya : OPEN curs3(23); Untuk curs1 diatas, perintah untuk membukanya : OPEN curs1 FOR SELECT * FROM mahasiswa; MENGGUNAKAN CURSOR Setelah cursor dibuka, nilainya dapat di manipulasi dengan perintah yang di deskripsikan disini : Untuk curs2, curs3 dan curs4 diatas, perintah untuk menggunakannya adalah : FETCH curs2 INTO v_nilai; FECTH curs3 INTO v_nilai; FETCH curs1 INTO v_nilai; Atau jika curs1 memiliki lebih dari satu kolom, anda dapat menggunakannya dengan cara : FETCH curs1 INTO v_nilai1, v_nilai2, v_nilai3; Setelah digunakan sebaiknya cursor ditutup untuk menghemat memory yang digunakan 13 | S t o r e d P r o c e d u r e
  • 14. CLOSE <nama_cursor>; Ex : CLOSE curs1; Contoh 8 : CREATE OR REPLACE FUNCTION isi_komentar1() RETURNS VOID AS $$ DECLARE v_nilai deret2.nilai%type; v_komentar deret2.komentar%type; c_nilai CURSOR IS SELECT nilai FROM deret2; BEGIN OPEN c_nilai; LOOP FETCH c_nilai INTO v_nilai; EXIT WHEN NOT FOUND; IF v_nilai>3 THEN v_komentar := 'BAGUS'; ELSE v_komentar := 'BIASA'; END IF; UPDATE deret2 SET komentar = v_komentar WHERE nilai = v_nilai; END LOOP; CLOSE c_nilai; END; $$ LANGUAGE 'plpgsql'; Contoh 9 : (Dari Presentasi Bpk Yudi Wbs) Diketahui: Tabel JAWABAN (NIM char, NO_SOAL int, JAWAB char) Tabel KUNCI (NO_SOAL int, KUNCI char) Isilah tabel SKOR (NIM char,SKOR int) dengan aturan: jawaban benar 4 point, jawaban salah -1. Tabel Jawaban : CREATE TABLE jawaban (nim char(6), no_soal integer, jawaban char(1)); Dummy data : INSERT INTO jawaban VALUES -- MAHASISWA 1, NIM : 123456 ('123456',1,'A'),('123456',2,'A'),('123456',3,'A'),('123456',4,'A'),('123456',5,'A'), ('123456',6,'A'),('123456',7,'A'),('123456',8,'A'),('123456',9,'A'),('123456',10,'A'), -- MAHASISWA 2, NIM : 234567 ('234567',1,'A'),('234567',2,'B'),('234567',3,'C'),('234567',4,'D'), ('234567',5,'B'), ('234567',6,'D'),('234567',7,'B'),('234567',8,'C'),('234567',9,'D'),('234567',10,'E'), -- MAHASISWA 3, NIM : 345678 ('345678',1,'A'), ('345678',2,'A'), ('345678',3,'C'), ('345678',4,'E'),('345678',5,'B'), ('345678',6,'D'),('345678',7,'E'),('345678',8,'A'),('345678',9,'D'),('345678',10,'A'), -- MAHASISWA 4, NIM 999999 ('999999',1,'B'), ('999999',2,'B'), ('999999',3,'D'), ('999999',4,'A'),('999999',5,'C'), ('999999',6,'A'),('999999',7,'C'),('999999',8,'B'),('999999',9,'A'),('999999',10,'A'); 14 | S t o r e d P r o c e d u r e
  • 15. Tabel kunci : CREATE TABLE kunci (no_soal integer, kunci char(1)); Dummy Data : INSERT INTO kunci VALUES (1,'A'), (2,'A'), (3,'C'), (4,'E'), (5,'B'), (6,'D'), (7,'E'), (8,'A'), (9,'D'), (10,'C'); Dengan Summary skor dari Dummy Data jawaban mahasiswa adalah seperti berikut : Mahasiswa 1, NIM 123456 : benar (3), salah (7) = (4*3) – (1*7) = 5 Mahasiswa 2, NIM 234567 : benar(5), salah (5) = (4*5) – (1*5) =15 Mahasiswa 3, NIM 345678 : benar(9), salah(1) = (4*9) – (1*1) = 35 Mahasiswa 4, NIM 999999 : benar(0), salah(10) = (4*0) – (1*10) = -10 Tabel Skor : CREATE TABLE skor (nim char(6), skor integer); Prosedur : CREATE OR REPLACE FUNCTION isi_skor() RETURNS VOID AS $$ DECLARE v_nim skor.nim%TYPE; v_skor skor.skor%TYPE; v_no_soal jawaban.no_soal%TYPE; v_jawaban jawaban.jawaban%TYPE; v_kunci kunci.kunci%TYPE; c_mahasiswa CURSOR IS SELECT DISTINCT nim FROM jawaban; c_jawaban CURSOR (v_nim_mhs jawaban.nim%TYPE)FOR SELECT no_soal, jawaban FROM jawaban WHERE nim = v_nim_mhs; c_kunci REFCURSOR; BEGIN OPEN c_mahasiswa; LOOP FETCH c_mahasiswa INTO v_nim; RAISE NOTICE 'nim : %', v_nim; EXIT WHEN NOT FOUND; v_skor := 0; OPEN c_jawaban(v_nim); LOOP FETCH c_jawaban INTO v_no_soal,v_jawaban; EXIT WHEN NOT FOUND; RAISE INFO 'no soal : %, jawaban : %', v_no_soal, v_jawaban; OPEN c_kunci FOR SELECT kunci FROM kunci WHERE no_soal = v_no_soal; FETCH c_kunci INTO v_kunci; RAISE INFO 'kunci : %', v_kunci; CLOSE c_kunci; IF v_jawaban <> v_kunci THEN RAISE INFO 'SALAH, %-1', v_skor; v_skor := v_skor-1; ELSE RAISE INFO 'BENAR, %+4', v_skor; v_skor := v_skor + 4; END IF; RAISE INFO 'skor : %', v_skor; END LOOP; INSERT INTO skor VALUES (v_nim, v_skor); CLOSE c_jawaban; END LOOP; CLOSE c_mahasiswa; END; $$ LANGUAGE 'plpgsql'; 15 | S t o r e d P r o c e d u r e
  • 16. Contoh 10 : (Dari Presentasi Bpk Yudi Wbs) Tabel input: TRANS_HARIAN (TGL date, JUM_TRANS int,ID_CUST int) Buatlah SP untuk mengisi tabel output: TRANS_BULANAN (THN int,BULAN int, JUM_TRANS int, ID_CUST int) TRANS_TAHUNAN (TAHUN int, JUM_TRANS int, ID_CUST int) Tabel Trans_Harian: CREATE TABLE trans_harian (tgl timestamp, jum_trans integer, id_cust integer); Dummy data : INSERT INTO trans_harian VALUES (to_timestamp('05 01 2000','DD MM YYYY'),12,1),(to_timestamp('06 01 2000','DD MM YYYY'),3,1),(to_timestamp('05 02 2000','DD MM YYYY'),4,2),(to_timestamp('07 01 2000','DD MM YYYY'),9,3),(to_timestamp('12 04 2000','DD MM YYYY'),1,1),(to_timestamp('05 01 2000','DD MM YYYY'),15,2),(to_timestamp('05 09 2000','DD MM YYYY'),21,1),(to_timestamp('05 10 2000','DD MM YYYY'),80,3),(to_timestamp('05 01 2001','DD MM YYYY'),8,1),(to_timestamp('05 02 2001','DD MM YYYY'),6,2),(to_timestamp('05 03 2001','DD MM YYYY'),9,3),(to_timestamp('05 04 2001','DD MM YYYY'),12,3),(to_timestamp('05 05 2001','DD MM YYYY'),13,3),(to_timestamp('05 06 2001','DD MM YYYY'),80,1),(to_timestamp('05 07 2001','DD MM YYYY'),19,2),(to_timestamp('05 08 2001','DD MM YYYY'),67,1),(to_timestamp('05 09 2001','DD MM YYYY'),999,2),(to_timestamp('05 10 2001','DD MM YYYY'),87,1),(to_timestamp('05 11 2001','DD MM YYYY'),90,2),(to_timestamp('05 12 2001','DD MM YYYY'),56,2),(to_timestamp('01 1 2002','DD MM YYYY'),76,1),(to_timestamp('15 1 2002','DD MM YYYY'),6,2),(to_timestamp('20 1 2002','DD MM YYYY'),96,3),(to_timestamp('05 2 2002','DD MM YYYY'),45,1),(to_timestamp('17 2 2002','DD MM YYYY'),67,2),(to_timestamp('13 2 2002','DD MM YYYY'),23,3),(to_timestamp('25 2 2002','DD MM YYYY'),84,1),(to_timestamp('21 2 2002','DD MM YYYY'),42,2),(to_timestamp('18 3 2002','DD MM YYYY'),45,3),(to_timestamp('12 3 2002','DD MM YYYY'),12,1),(to_timestamp('16 3 2002','DD MM YYYY'),67,2),(to_timestamp('19 3 2002','DD MM YYYY'),86,3),(to_timestamp('22 3 2002','DD MM YYYY'),56,1),(to_timestamp('23 3 2002','DD MM YYYY'),43,2),(to_timestamp('24 3 2002','DD MM YYYY'),90,3),(to_timestamp('01 4 2002','DD MM YYYY'),75,1),(to_timestamp('02 4 2002','DD MM YYYY'),45,2),(to_timestamp('11 4 2002','DD MM YYYY'),65,3),(to_timestamp('13 4 2002','DD MM YYYY'),57,1),(to_timestamp('14 5 2002','DD MM YYYY'),43,2),(to_timestamp('17 5 2002','DD MM YYYY'),93,3),(to_timestamp('28 5 2002','DD MM YYYY'),34,1),(to_timestamp('26 6 2002','DD MM YYYY'),67,2),(to_timestamp('21 7 2002','DD MM YYYY'),32,3),(to_timestamp('22 7 2002','DD MM YYYY'),43,1),(to_timestamp('23 7 2002','DD MM YYYY'),56,2),(to_timestamp('24 7 2002','DD MM YYYY'),97,3),(to_timestamp('01 8 2002','DD MM YYYY'),91,1),(to_timestamp('01 9 2002','DD MM YYYY'),23,2),(to_timestamp('05 12 2002','DD MM YYYY'),576,3); Tabel Trans_bulanan CREATE TABLE trans_bulanan(thn integer, bulan integer, jum_trans integer, id_cust integer); Tabel Trans_tahunan CREATE TABLE trans_tahunan(thn integer, jum_trans integer, id_cust integer); Prosedur-Prosedur : Cust_per_tahun CREATE OR REPLACE FUNCTION cust_per_tahun (v_tahun INTEGER) RETURNS REFCURSOR AS $$ DECLARE v_curs_thn REFCURSOR; BEGIN OPEN v_curs_thn FOR SELECT DISTINCT id_cust FROM trans_harian WHERE EXTRACT (year FROM tgl) = v_tahun; RETURN (v_curs_thn); END; $$ LANGUAGE 'plpgsql'; Trans_thn_cust CREATE OR REPLACE FUNCTION trans_thn_cust (v_tahun INTEGER, v_id_cust INTEGER) RETURNS INTEGER AS $$ DECLARE 16 | S t o r e d P r o c e d u r e
  • 17. jmlh_trans INTEGER; BEGIN SELECT INTO jmlh_trans SUM(jum_trans) FROM trans_harian WHERE id_cust = v_id_cust AND EXTRACT (YEAR FROM tgl) = v_tahun; RETURN (jmlh_trans); END; $$ LANGUAGE 'plpgsql'; Trans_bln_cust CREATE OR REPLACE FUNCTION trans_bln_cust (v_tahun INTEGER, v_bulan INTEGER, v_id_cust INTEGER) RETURNS INTEGER AS $$ DECLARE jmlh_trans INTEGER; BEGIN SELECT INTO jmlh_trans SUM(jum_trans) FROM trans_harian WHERE id_cust = v_id_cust AND EXTRACT (MONTH FROM tgl) = v_bulan AND EXTRACT (YEAR FROM tgl) = v_tahun; RETURN (jmlh_trans); END; $$ LANGUAGE 'plpgsql'; Isi_summary_trans jalankan fungsi ini untuk mengisi tabel trans bulanan dan tahunan. CREATE OR REPLACE FUNCTION isi_summary_trans() RETURNS VOID AS $$ DECLARE v_tahun INTEGER; v_bulan INTEGER; v_id_cust INTEGER; v_trans_cust_thn INTEGER; v_trans_cust_bln INTEGER; c_tahun CURSOR IS SELECT DISTINCT EXTRACT (YEAR FROM tgl) FROM trans_harian; c_cust_thn REFCURSOR; BEGIN OPEN c_tahun; LOOP FETCH c_tahun INTO v_tahun; EXIT WHEN NOT FOUND; c_cust_thn := cust_per_tahun(v_tahun); LOOP FETCH c_cust_thn INTO v_id_cust; EXIT WHEN NOT FOUND; v_trans_cust_thn := trans_thn_cust (v_tahun,v_id_cust); INSERT INTO trans_tahunan VALUES (v_tahun,v_trans_cust_thn,v_id_cust); v_bulan := 1; FOR v_bulan IN 1..12 LOOP v_trans_cust_bln := trans_bln_cust(v_tahun,v_bulan,v_id_cust); INSERT INTO trans_bulanan VALUES(v_tahun,v_bulan,v_trans_cust_bln,v_id_cust); END LOOP; END LOOP; CLOSE c_cust_thn; END LOOP; CLOSE c_tahun; END; $$ LANGUAGE 'plpgsql'; 17 | S t o r e d P r o c e d u r e
  • 18. Tahun/Customer 2000 2001 2002 Bulan 1 2 3 1 2 3 1 2 3 1 15 15 9 8 76 6 96 2 4 6 129 109 23 3 9 68 110 221 4 12 132 45 65 5 13 34 43 93 6 80 67 7 19 43 56 129 8 67 91 9 21 999 23 10 80 87 11 90 12 56 576 Total 37 19 89 242 1170 34 573 459 1203 18 | S t o r e d P r o c e d u r e
  • 19. <(Pengayaan)> DEKLARASI VARIABEL nama_variabel [ CONSTANT ] type_data [ NOT NULL ] [ { DEFAULT | := } nilai_awal ]; CONSTANT : nilai variabel tidak dapat di ubah. NOT NULL : nilai variabel tidak boleh bernilai null. DEFAULT : Nilai default selalu di evaluasi tiap suatu block di masuki. Sebagai contoh, menggunakan now() sebagai nilai default akan membuat variabel memiliki nilai waktu saat fungsi tersebut di eksekusi. Jika menggunakan := now(), akan membuat variabel memiliki nilai waktu saat fungsi tersebut di compile. Contoh : quantity integer DEFAULT 32; url varchar := „http://mysite.com‟; user_id CONSTANT integer := 10; ALIAS UNTUK PARAMETER FUNGSI Parameter yang di kirimkan ke fungsi secara default di identifikasikan dengan $1, $2, etc. Untuk memudahkan pembacaan fungsi, nama alias dapat di pergunakan(ini yang di pergunakan sebagai contoh-contoh diatas). Namun parameter yang di beri nama alias masih tetap dapat direferensikan dengan nama default $1, $2, ect. Ada dua cara untuk membuat alias. Cara yang sering digunakan adalah dengan memberi nama alias pada pembuatan fungsi. Contoh : CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$ BEGIN RETURN subtotal * 0.06; END; $$ LANGUAGE plpgsql; Cara kedua, adalah satu-satunya cara yang di perbolehkan pada versi sebelum 8.0 : CREATE FUNCTION sales_tax(real) RETURNS real AS $$ DECLARE subtotal ALIAS FOR $1; BEGIN RETURN subtotal * 0.06; END; $$ LANGUAGE plpgsql; Alias untuk Parameter Output Saat fungsi PL/pgSQL mendeklarasikan parameter output, parameter output tersebut juga diidentifikasikan dengan $n, paramaeter output ini dapat juga di beri nama alias sama seperti parameter input. Parameter output adalah parameter yang bernilai NULL, dan harus diisikan nilainya pada saat eksekusi fungsi. Nilai akhir dari parameter adalah nilai yang di hasilkan(yang di 19 | S t o r e d P r o c e d u r e
  • 20. RETURN) oleh fungsi tersebut. Bentuk lain dari output parameter RETURNS pada deklarasi fungsi adalah dengan mendefinisikan OUT pada parameter fungsi. Contoh : CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ BEGIN tax := subtotal * 0.06; END; $$ LANGUAGE plpgsql; Dapat dilihat pada fungsi diatas, tidak ada pendeklarasian RETURN, anda dapat mendeklarasikan RETURN, namun hal tersebut akan menghasilkan redudansi pada badan fungsi. Parameter output seperti ini akan sangat berguna saat fungsi menghasilkan lebih dari satu variabel hasil. Contoh : CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ BEGIN sum := x + y; prod := x * y; END; $$ LANGUAGE plpgsql; VARIABEL BERTIPE DATA COMPOSITE (CAMPURAN) Pada lingkungan programming, tipe data campuran seringkali digunakan untuk menangani berbagai masalah seperti Lingked List, Stack, Queue, Tree, Graph dll. Contoh : Tipe data titik dengan dua variabel (x, y) PADA LINGKUNGAN PEMROGRAMAN JAVA Deklarasi variabel ini dapat di lakukan dengan cara membuat kelas baru yang dinamakan kelas titik public class titik { public int x = 0; public int y = 0; } Anda dapat menggunakan kelas ini dengan membuat objek baru dengan properties kelas, misalkan anda ingin menggambar garis dari titik A ke titik B, maka anda harus membuat objek titik A dan objek titik B. public class garis { Public static void main (String[] args) { public titik A = new titik(); public titik B = new titik(); /* gambar garis dari titik (4, 5) dan (9, 8) */ A.x = 4; A.y = 5; B.x = 9; B.y = 8; System.out.println(“ garis dari (“+A.x+”,”+A.y”) ke (“+B.x+”,”+B.y”)”); } } 20 | S t o r e d P r o c e d u r e
  • 21. PADA LINGKUNGAN PEMROGRAMAN C/C++ Deklarasi variabel dilakukan dengan cara membuat tipe data baru, yang lalu di pergunakan dalam badan fungsi. #include <stdio.h> main() { struct titik { int x; int y; } titik A; titik B; /* gambar garis dari titik (4, 5) dan (9, 8) */ A.x = 4; A.y = 5; B.x = 9; B.y = 8; printf(“ garis dari (%d,%d) ke (%d,%d)”, A.x, A.y, B.x, B.y); } PADA LINGKUNGAN POSTGRESQL Pada contoh-contoh sebelumnya fungsi-fungsi hanya menggunakan tipe data bawaan dari postgreSQL, sebenarnya kita dapat membuat tipe data sendiri dengan cara CREATE TYPE <nama_tipe> AS ( <nama_variabel> <tipe_data_variabel> ); Contoh : CREATE TYPE titik AS ( x integer, y integer ); Tipe data baru ini dapat anda pergunakan untuk berbagai keperluan, misalkan membuat tabel dengan kolom dengan tipe data ini, maupun menggunakan tipe data ini pada fungsi. Contoh : CREATE TABEL garis (a titik, b titik); INSERT INTO garis VALUES ((2,3),(4,5)); INSERT INTO garis VALUES ((3,9),(8,5)); INSERT INTO garis VALUES ((2,6),(4,6)); SELECT (a).x FROM garis; -- atau jika anda menggunakan nama tabel untuk operasi multi tabel SELECT (garis.a).x FROM garis; SELECT * FROM garis WHERE (a).x = 2; SELECT * FROM garis WHERE (b).y = 5; -- pada operasi update, kita tidak boleh menggunakan tanda kurung setelah SET UPDATE garis SET (b).y = 99 WHERE (b).y = 5; -- ERROR UPDATE garis SET b.y = 99 WHERE (b).y = 5; -- tetapi tanda kurung harus digunakan saat mereferensi kolom yang sama pada -- ekspresi di sebelah kanan tanda sama dengan UPDATE garis SET a.x = (a).x + 1 WHERE (a).x = 3; -- kita juga dapat menggunakan sub-field ini sebagai sasaran operasi insert INSERT INTO garis (a.x, b.y) VALUES (99, 55); 21 | S t o r e d P r o c e d u r e
  • 22. Seperti telah disebutkan diatas, kita juga dapat membuat fungsi dengan tipe data campuran ini. CREATE FUNCTION masukkan_titik_a_ke_garis (v_a_x integer, v_a_y integer) RETURNS VOID AS $$ BEGIN INSERT INTO garis (a.x, a.y) VALUES (v_a_x, v_a_y); END; $$ LANGUAGE 'plpgsql'; Anda dapat mengeksekusi fungsi diatas dengan cara : select masukkan_titik_a_ke_garis(25,67); dengan tipe data campuran ini, anda diberikan kebebasan dalam pemrograman dengan hanya mengeluarkan satu variabel yang mengandung isi lebih dari satu variabel. 22 | S t o r e d P r o c e d u r e