SlideShare a Scribd company logo
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

More Related Content

PDF
PostgreSQL Trigger
PPT
11 Sistem Pendukung Keputusan
PPTX
Erp pertemuan-7
PDF
Laporan praktek kerja lapangan
DOCX
Proposal Business Plan - business
DOCX
Proposal kewirausahaan ayam goreng pedasssss
PDF
Contoh peraturan perusahaan bucah
PDF
Metodologi Penelitian pada Bidang Ilmu Komputer dan Teknologi Informasi
PostgreSQL Trigger
11 Sistem Pendukung Keputusan
Erp pertemuan-7
Laporan praktek kerja lapangan
Proposal Business Plan - business
Proposal kewirausahaan ayam goreng pedasssss
Contoh peraturan perusahaan bucah
Metodologi Penelitian pada Bidang Ilmu Komputer dan Teknologi Informasi

What's hot (20)

PDF
Database with SQL Server
PPT
Aspek ergonomi dalam IMK
PPTX
01. pengenalan ms access
PDF
Kd4 fungsi fungsi agregasi
PPT
7. line balancing
PPT
Linear Programming Project
PDF
Final Project APSI : ANALISIS PERANCANGAN SISTEM INFORMASI PENJUALAN SUPERMAR...
PPTX
Penjadwalan Produksi Induk
PDF
Sistem pendukung keputusan seleksi penerima calon guru honor upload
PDF
4.1 Operasi Dasar Singly Linked List 1 (primitive list)
PDF
PowerPoint entity relationship diagram
PDF
Panduan Pengguna Linux RedHat
PPT
Chapt 4. interaction(interaksi)
PPTX
Scheduling - Sistem Operasi (Kelompok 3)
PPT
Study kasus six sigma
PPTX
Power point smk penjualan usaha kue
PDF
Elemen simulasi
PDF
M4 kb4 penyusunan perjalanan dinas
PDF
Model simulasi(2)
PDF
Makalah Aplikasi Database Maskapai Penerbangan
Database with SQL Server
Aspek ergonomi dalam IMK
01. pengenalan ms access
Kd4 fungsi fungsi agregasi
7. line balancing
Linear Programming Project
Final Project APSI : ANALISIS PERANCANGAN SISTEM INFORMASI PENJUALAN SUPERMAR...
Penjadwalan Produksi Induk
Sistem pendukung keputusan seleksi penerima calon guru honor upload
4.1 Operasi Dasar Singly Linked List 1 (primitive list)
PowerPoint entity relationship diagram
Panduan Pengguna Linux RedHat
Chapt 4. interaction(interaksi)
Scheduling - Sistem Operasi (Kelompok 3)
Study kasus six sigma
Power point smk penjualan usaha kue
Elemen simulasi
M4 kb4 penyusunan perjalanan dinas
Model simulasi(2)
Makalah Aplikasi Database Maskapai Penerbangan
Ad

Similar to PostgreSQL Stored-procedure (14)

PPTX
membuat function dalam mysql
PDF
Pertemuan 09 (procedure dan function database)
DOCX
Materi my sql part 5
DOC
Contoh store procedure dan function
DOC
Laporan 4
DOC
Laporan 4
PPTX
Pbd function
PDF
Modul 07 basisdata
PPTX
#7 - Stored Procedure And Function.pptx
PPT
6. subrutin
DOC
11 percabangan pl sql
DOCX
Kamus pl sql
DOC
membuat function dalam mysql
Pertemuan 09 (procedure dan function database)
Materi my sql part 5
Contoh store procedure dan function
Laporan 4
Laporan 4
Pbd function
Modul 07 basisdata
#7 - Stored Procedure And Function.pptx
6. subrutin
11 percabangan pl sql
Kamus pl sql
Ad

More from Ammar Shadiq (7)

PDF
Statement of Accomplisment from Online Machine Learning Class
PDF
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
PDF
PostgreSQL Transaksi
PDF
Pengenalan konsep dan komponen Oracle database recovery
PDF
Oracle transaksi
ODT
Java numbers
ODP
Pelatihan Java - Number & String
Statement of Accomplisment from Online Machine Learning Class
Mendeteksi Topik Berita Pada Aliran Berita Online Berbahasa Indonesia
PostgreSQL Transaksi
Pengenalan konsep dan komponen Oracle database recovery
Oracle transaksi
Java numbers
Pelatihan Java - Number & String

Recently uploaded (9)

DOCX
Keutuhan Aplikasi Konsep dan Praktik dalam Upaya menciptakan aplikasi Anti Vi...
PPT
pengantar-sistem-informasi manajemen.ppt
DOCX
Antivirus Versi.FULL.JALiN.KB.PRO Keutuhan Aplikasi Konsep dan Praktik dalam ...
PPTX
Peranan AI dalam Dunia Pendidikan dan Industri Aplikasinya
PPTX
Materi asdsa asd asd sad sa dsa dsa d sa
PDF
Modul_Pemula_Merakit_Komputer untuk smppdf
PPTX
Materi_Array_Karakter_String untuk kelas XI sma.pptx
PDF
Rekomendasi Riset Lanjutan : perspektif_futurologis.pdf
PPTX
Implementasi Microservices pada Manufaktur
Keutuhan Aplikasi Konsep dan Praktik dalam Upaya menciptakan aplikasi Anti Vi...
pengantar-sistem-informasi manajemen.ppt
Antivirus Versi.FULL.JALiN.KB.PRO Keutuhan Aplikasi Konsep dan Praktik dalam ...
Peranan AI dalam Dunia Pendidikan dan Industri Aplikasinya
Materi asdsa asd asd sad sa dsa dsa d sa
Modul_Pemula_Merakit_Komputer untuk smppdf
Materi_Array_Karakter_String untuk kelas XI sma.pptx
Rekomendasi Riset Lanjutan : perspektif_futurologis.pdf
Implementasi Microservices pada Manufaktur

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