PL/SQL Packages

Perlu kita ingat bersama, initialization part dari sebuah package hanya dijalankan sekali saja, saat pertama kali kita mereferensi kepada package tersebut. Jadi, di dalam contoh terakhir, hanya satu baris data yang ditambahkan ke dalam database table emp_audit. Demikian juga, variable number_hired diinisialisasi hanya sekali.

Setiap kali procedure hire_employee dipanggil, variabel number_hired di-update. Namun, perhitungan yang dipegang oleh number_hired bersifat spesifik terhadap session. Yaitu, perhitungan tersebut merefleksikan jumlah karyawan baru yang diproses oleh satu user, bukan jumlah yang diproses oleh seluruh user.

Dalam contoh berikutnya, kita mem-package-kan beberapa transaksi perbankan yang mirip. Mari kita asumsikan bahwa transaksi-transaksi debit dan kredit dimasukkan setelah jam-jam kerja melalui ATM (Automatic Teller Machine), kemudian diaplikasikan terhadap rekening pada keesokan harinya.

CREATE PACKAGE bank_transactions AS
/* Declare externally visible constant. */
minimum_balance CONSTANT REAL := 100.00;
/* Declare externally callable procedures. */
PROCEDURE apply_transactions;
PROCEDURE enter_transaction (
acct INT,
kind CHAR,
amount REAL);
END bank_transactions;
CREATE PACKAGE BODY bank_transactions AS
  /* Declare global variable to hold transaction status. */
  new_status VARCHAR2(70) := ’Unknown’;
  /* Use forward declarations because apply_transactions
  calls credit_account and debit_account, which are not
  yet declared when the calls are made. */
  PROCEDURE credit_account (acct INT, credit REAL);
  PROCEDURE debit_account (acct INT, debit REAL);
  /* Fully define procedures specified in package. */
  PROCEDURE apply_transactions IS
  /* Apply pending transactions in transactions table
  to accounts table. Use cursor to fetch rows. */
  CURSOR trans_cursor IS
    SELECT acct_id, kind, amount FROM transactions
    WHERE status = 'Pending'
    ORDER BY time_tag
    FOR UPDATE OF status; -- to lock rows
BEGIN
  FOR trans IN trans_cursor LOOP
    IF trans.kind = 'D' THEN
      debit_account(trans.acct_id, trans.amount);
    ELSIF trans.kind = 'C' THEN
      credit_account(trans.acct_id, trans.amount);
    ELSE
      new_status := 'Rejected';
    END IF;
    UPDATE transactions SET status = new_status
    WHERE CURRENT OF trans_cursor;
  END LOOP;
END apply_transactions;
PROCEDURE enter_transaction (
/* Add a transaction to transactions table. */
acct INT,
kind CHAR,
amount REAL) IS
BEGIN
  INSERT INTO transactions
  VALUES (acct, kind, amount, 'Pending', SYSDATE);
END enter_transaction;
/* Define local procedures, available only in package. */
PROCEDURE do_journal_entry (
/* Record transaction in journal. */
acct INT,
kind CHAR,
new_bal REAL) IS
BEGIN
  INSERT INTO journal
  VALUES (acct, kind, new_bal, sysdate);
  IF kind = 'D' THEN
    new_status := 'Debit applied';
  ELSE
    new_status := 'Credit applied';
  END IF;
END do_journal_entry;
PROCEDURE credit_account (acct INT, credit REAL) IS
/* Credit account unless account number is bad. */
old_balance REAL;
new_balance REAL;
BEGIN
  SELECT balance INTO old_balance FROM accounts
  WHERE acct_id = acct
  FOR UPDATE OF balance; -- to lock the row
  new_balance := old_balance + credit;
  UPDATE accounts SET balance = new_balance
  WHERE acct_id = acct;
  do_journal_entry(acct, 'C', new_balance);
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      new_status := 'Bad account number';
    WHEN OTHERS THEN
      new_status := SUBSTR(SQLERRM,1,70);
END credit_account;
PROCEDURE debit_account (acct INT, debit REAL) IS
/* Debit account unless account number is bad or
account has insufficient funds. */
old_balance REAL;
new_balance REAL;
insufficient_funds EXCEPTION;
BEGIN
  SELECT balance INTO old_balance FROM accounts
  WHERE acct_id = acct
  FOR UPDATE OF balance; -- to lock the row
  new_balance := old_balance - debit;
  IF new_balance >= minimum_balance THEN
    UPDATE accounts SET balance = new_balance
    WHERE acct_id = acct;
    do_journal_entry(acct, 'D', new_balance);
  ELSE
    RAISE insufficient_funds;
  END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      new_status := 'Bad account number';
    WHEN insufficient_funds THEN
      new_status := 'Insufficient funds';
    WHEN OTHERS THEN
      new_status := SUBSTR(SQLERRM,1,70);
END debit_account;
END bank_transactions;

Dalam package ini, initialization part digunakan.

9.6. Private Versus Public Items dalam Packages

Marilah kita lihat kembali package emp_actions. Package body-nya mendeklarasikan sebuah variable bernama number_hired, yang diinisialisasi dengan nol. Tidak seperti item-item yang di deklarasikan di dalam spec dari emp_actions, item-item yang dideklarasikan di dalam body tersebut terbatas untuk digunakan di dalam package tersebut. Dengan demikian, PL/SQL code di luar package tersebut tidak dapat mereferensi variable number_hired. Item-item seperti ini disebut private.

Namun, item-item yang dideklarasikan di dalam spec dari emp_actions, seperti halnya exception invalid_salary, terlihat dari luar package. Dengan demikian, sebuah PL/SQL code dapat mereferensi terhadap exception invalid_salary tersebut. Item-item seperti ini disebut public.

Ketika kita harus memelihara item-item melalui sebuah session atau diantara transaksi-transaksi, kita letakkan mereke di dalam declarative part dari package body tersebut. Sebagai contoh, nilai dari number_hired ialah tetap diantara pemanggilan terhadap hire_employee di dalam session yang sama. Nilai tersebut akan hilang ketika session tersebut berakhir.

Jika kita harus membuat item-item menjadi public, kita letakkan mereka di dalam package spec. Sebagai contoh, konstanta minimum_balance yang di deklarasikan di dalam spec dari package bank_transactions tersedia untuk digunakan secara umum.

 

Pages: 1 2 3 4 5 6 7

 

Buku ini membahas berbagai macam tip dan trik yang sangat berguna bagi Anda pembaca pengguna database Oracle. Pemula, mahasiswa, programmer, maupun database administrator yang mengharapkan solusi cepat dalam menangani permasalahan-permasalahan dalam penggunaan database Oracle dapat membaca buku ini. Anda tidak harus membaca buku ini secara urut karena buku ini di susun berdasarkan topik permasalahan, dan Anda dapat membaca topik-topik yang sesuai dengan permasalahan yang Anda hadapi.
Dapat di beli di toko buku Gramedia, Gunung Agung, Uranus, Karisma dsb. Harga Rp. 24.800,- (157 halaman)

 

Related Articles

 

Comments

[…] Silahkan melanjutkan membaca pembahasan PL/SQL Packages […]

[…] PL/SQL PackagesPL/SQL Object TypesNative Dynamic SQLMenangani PL/SQL ErrorsInteraksi PL/SQL dengan Oracle […]

wah, dapet materi lagi soal package pl sql..

Leave a comment

(required)

(required)


*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word