Dasar-dasar PL/SQL

Pada pembahasan sebelumnya kita telah mengenal sedikit banyak tentang PL/SQL. Pembahasan kali ini fokus kepada aspek-aspek skala-kecil dari PL/SQL, yaitu dasar-dasar PL/SQL. Seperti setiap bahasa pemrograman lainnya, PL/SQL memiliki character set (kumpulan karakter), reserved words (kata-kata yang telah dipesan dan tidak boleh kita gunakan, misalnya: procedure, function, dsb), tanda baca, tipe-tipe data, sintaks tertentu, dan aturan yang tetap dalam hal penggunaan dan formasi penulisan sintaks. Kita menggunakan elemen-elemen dasar dari PL/SQL untuk merepresentasikan objek-objek di dunia nyata serta operasi-operasinya.

Kali ini kita akan membahas topik-topik berikut ini:

2.1. Character Set

Kita menulis program PL/SQL dalam baris teks dengan menggunakan kumpulan karakter tertentu. Kumpulan karakter PL/SQL terdiri dari:

PL/SQL tidak case-sensitive, sehingga huruf kecil sama dengan huruf besar kecuali di dalam string atau character literals.

2.2. Lexical Units

Baris teks PL/SQL mengandung kumpulan-kumpulan karakter yang disebut dengan lexical units, dimana dapat diklasifikasikan menjadi:

Untuk meningkatkan kemudahan pembacaan, kita dapat memisahkan lexical units dengan spasi. Pada kenyataannya, kita harus memisahkan identifier-identifier yang berdekatan dengan spasi atau tanda baca. Baris berikut ini tidak diperbolehkan karena reserved words END dan IF digabung:

IF x > y THEN high := x; ENDIF; -- tidak diperbolehkan

Namun, kita tidak bisa menyertakan spasi di dalam lexical units kecuali untuk string literals dan komentar. Sebagai contoh, baris berikut ini tidak diperbolehkan karena gabungan simbol assignment (:=) dipisah:

count : = count + 1; -- tidak diperbolehkan

Untuk menunjukkan struktur, kita dapat memecah baris-baris dengan menggunakan enter dan baris-baris yang menjorok ke dalam dengan menggunakan spasi atau tab. Bandingkan kemudahaan pembacaan dari kedua perintah-perintah IF berikut ini:

IF x>y THEN max:=x; ELSE max:=y; END IF;

atau

IF x > y THEN
  max := x;
ELSE
  max := y;
END IF;

2.2.1. Delimiters

Delimiter adalah simbol sederhana atau gabungan yang memiliki arti khusus bagi PL/SQL. Sebagai contoh, kita dapat menggunakan delimiters untuk merepresentasikan operasi-operasi aritmatika seperti penjumlahan dan pengurangan. Simbol sederhana terdiri dari satu karakter. Daftarnya adalah sebagai berikut:

+ addition operator
% attribute indicator
‘ character string delimiter
. component selector
/ division operator
( expression or list delimiter
) expression or list delimiter
: host variable indicator
, item separator
* multiplication operator
” quoted identifier delimiter
= relational operator
< relational operator
> relational operator
@ remote access indicator
; statement terminator
- subtraction/negation operator

Simbol gabungan terdiri dari dua karakter. Daftarnya adalah sebagai berikut:

:= assignment operator
=> association operator
|| concatenation operator
** exponentiation operator
<< label delimiter (begin)
>> label delimiter (end)
/* multi-line comment delimiter (begin)
*/ multi-line comment delimiter (end)
.. range operator
<> relational operator
!= relational operator
~= relational operator
^= relational operator
<= relational operator
>= relational operator
– single-line comment indicator

2.2.2. Identifiers

Kita menggunakan identifiers untuk menamai item-item dan unit-unit program PL/SQL, termasuk constants (konstanta), variables, exceptions, cursors, cursor variables, subprograms, dan packages. Beberapa contoh identifiers adalah sebagai berikut:

X
t2
phone#
credit_limit
LastName
oracle$number

Suatu identifier terdiri dari huruf yang secara opsional diikuti oleh huruf-huruf, angka-angka, simbol-simbol dollar, garis-garis bawah, dan tanda-tanda angka. Karakter-karakter lain seperti tanda penghubung, garis miring, dan spasi tidak diperbolehkan, seperti yang ditunjukkan oleh contoh-contoh di bawah ini:

mine&yours -- tidak diperbolehkan karena ampersand
debit-amount -- tidak diperbolehkan karena hyphen
on/off -- tidak diperbolehkan karena slash
user id -- tidak diperbolehkan karena space

Contoh-contoh lain menunjukkan diperbolehkannya gabungan simbol dollar, garis bawah, dan  tanda-tanda angka:

money$$$tree
SN##
try_again_

Kita dapat menggunakan huruf besar, huruf kecil, atau gabungan keduanya untuk menulis identifier. PL/SQL tidak case-sensitive kecuali di dalam string dan character literals. Jadi, jika perbedaan antara identifier-identifier hanyalah masalah besar kecilnya huruf, maka PL/SQL akan menganggapnya sama, seperti ditunjukkan oleh contoh berikut ini:

lastname
LastName -- sama dengan lastname
LASTNAME -- sama dengan lastname dan LastName

Ukuran sebuah identifier tidak dapat melebihi 30 karakter. Namun, setiap karakter, termasuk tanda dollar, garis bawah, dan tanda angka, memiliki arti tersendiri. Sebagai contoh, PL/SQL akan menganggap identifier-identifier berikut ini berbeda satu sama lain:

lastname
last_name

Identifier sebaiknya deskriptif. Jangan menggunakan nama-nama yang tidak jelas, seperti cpm. Sebaiknya gunakan nama-nama yang memiliki arti seperti cost_per_thousand.

2.2.2.1. Reserved Words

Beberapa identifier, yang disebut dengan reserved words, memiliki arti khusus untuk PL/SQL, dan sebaiknya tidak kita definisikan ulang. Sebagai contoh, kata-kata BEGIN dan END, yang mana digunakan untuk menandai bagian executable dari suatu blok atau subprogram, merupakan reserved words. Seperti ditunjukkan oleh contoh berikut ini, jika kita berusaha mendefinisikan ulang reserved word, kita akan mendapatkan error:

DECLARE
end BOOLEAN; -- tidak diperbolehkan; menyebabkan compilation error

Namun, kita dapat menyertakan reserved words di dalam sebuah identifier, seperti contoh berikut ini:

DECLARE
end_of_game BOOLEAN; -- diperbolehkan

Seringkali, reserved words ditulis di dalam huruf besar untuk memudahkan pembacaan. Namun, seperti halnya identifier-identifier PL/SQL lainnya, reserved words dapat juga ditulis di dalam huruf kecil atau gabungan huruf kecil dan besar.

2.2.2.2. Predefined Identifiers

Identifiers yang secara global dideklarasikan di dalam package STANDARD, seperti halnya exception INVALID_NUMBER, dapat dideklarasikan ulang. Namun, mendeklarasikan ulang predefined identifiers merupakan kesalahan karena deklarasi lokal kita akan menolak deklarasi global.

2.2.2.3. Quoted Identifiers

Untuk fleksibilitas, PL/SQL mengijinkan kita untuk menutup identifiers dengan tanda petik dua. Quoted identifiers jarang dibutuhkan, namun sesekali mereka dapat berguna. Mereka dapat mengandung suatu sequence dari printable characters termasuk spasi, tetapi tidak termasuk tanda petik ganda. Sehingga, identifier-identifier berikut ini valid:

"X+Y"
"last name"
"on/off switch"
"employee(s)"
"*** header info ***"

Ukuran maksimum dari quoted identifier adalah 30 karakter tidak termasuk tanda petik ganda. Meskipun diperbolehkan, penggunaan reserved words PL/SQL yang diapit tanda petik ganda merupakan cara pemrograman yang buruk.

Beberapa reserved words PL/SQL bukan merupakan reserved words bagi SQL. Sebagai contoh, kita dapat menggunakan reserved words PL/SQL seperti TYPE di dalam perintah CREATE TABLE untuk menamai kolom pada database. Tetapi, jika perintah SQL pada program kita mengacu kepada kolom tersebut, kita akan mendapatkan pesan kesalahan, seperti ditunjukkan oleh contoh berikut ini:

SELECT acct, type, bal INTO ... -- menyebabkan compilation error

Untuk mencegah terjadinya kesalahan, apitlah kolom di dalam huruf kapital tersebut dengan tanda petik ganda, seperti contoh berikut:

SELECT acct, "TYPE", bal INTO ...

Nama kolom tidak dapat tampak dalam huruf kecil atau gabungan huruf kecil dan besar (kecuali ia dedefinisikan seperti itu dalam perintah CREATE TABLE). Sebagai contoh, perintah berikut adalah salah:

SELECT acct, "type", bal INTO ... -- menyebabkan compilation error

Alternatifnya, ktia dapat menciptakan view untuk mengubah nama-nama kolom yang bermasalah tersebut, dan kemudian menggunakan view tersebut, bukannya base table-nya di dalam perintah-perintah SQL.

2.2.3. Literals

Literal merupakan numerik, karakter, string, atau nilai Boolean eksplisit, yang tidak direpresentasikan oleh identifier. Literal numerik 147 dan literal Boolean FALSE adalah contohnya.

2.2.3.1. Numeric Literals

Dua jenis numeric literals dapat digunakan di dalam ekspresi-ekspresi aritmatika: integer dan real. Literal integer adalah angka tanpa tanda desimal, serta dapat bernilai positif atau negatif. Beberapa contohnya adalah:

030 6 -14 0 +32767

Literal real adalah angka dengan tanda desimal, serta dapat bernilai positif atau negatif. Beberapa contohnya adalah:

6.6667 0.0 -12.0 3.14159 +8300.00 .5 25.

PL/SQL menganggap angka-angka seperti 12.0 dan 25. sebagai real meskipun mereka memiliki nilai-nilai integer.

Literal-literal numerik tidak dapat mengandung tanda-tanda dollar atau koma, tetapi dapat ditulis dengan menggunakan notasi scientific. Secara sederhana kita dapat menambahkan angka dengan E (atau e) kemudian secara opsional dapat diikuti oleh tanda-tanda integer. Beberapa contohnya adalah:

2E5 1.0E-7 3.14159e0 -1E38 -9.5e-3

E berarti “sepuluh kali terhadap pangkat dari”. Seperti pada contoh berikut, angka setelah E merupakan pangkat dari 10 dimana angka sebelum E harus dikalikan (tanda asterisk ganda (** ) merupakan operator eksponensial):

5E3 = 5 * 10**3 = 5 * 1000 = 5000

Angka setelah E juga berkorespondensi terhadap jumlah tempat untuk poin desimal. Pada contoh terakhir, desimal poin implisit menempati tiga tempat ke kanan. Dalam contoh ini, ia menempati tiga tempat ke kiri:

5E-3 = 5 * 10**-3 = 5 * 0.001 = 0.005

Seperti ditunjukkan oleh contoh berikut ini, jika nilai literal numerik berkurang dan keluar dari jangkauan 1E-130 .. 10E125, kita akan mendapatkan pesan error.

DECLARE
n NUMBER;
BEGIN
n := 10E127; -- menyebabkan error 'numeric overflow or underflow'

2.2.3.2. Character Literals

Literal karakter merupakan karakter individual yang diapit oleh tanda petik tunggal. Literal-literal karakter termasuk seluruh karakter cetak dalam kumpulan karakter PL/SQL: huruf-huruf, angka-angka, spasi-spasi, dan simbol-simbol khusus. Beberapa contohnya adalah:

'Z' '%' '7' ' ' 'z' '('

PL/SQL adalah case sensitive dalam literal-literal karakter. Sebagai contoh, PL/SQL menganggap bahwa literal-literal ‘Z’ dan ‘z’ adalah berbeda. Juga, literal-literal ‘0’..’9’ tidak sama dengan literal-literal integer tetapi dapat digunakan dalam ekspresi-ekspresi aritmatika karena mereka secara implisit dapat dikonversi menjadi integer.

2.2.3.3. String Literals

Nilai karakter dapat direpresentasikan oleh identifier atau seara eksplisit ditulis sebagai literal string, dimana terdiri dari nol atau lebih karakter-karakter yang diapit oleh tanda petik tunggal. Beberapa contohnya adalah:

'Hello, world!' 'XYZ Corporation' '10-NOV-91' 'He said "Life is like licking honey from a thorn."' '$1,000,000'

Seluruh literal-literal string kecuali string null (”) memiliki tipe data CHAR.

Telah dijelaskan bahwa tanda petik tunggal men-delimit literal-literal string, maka bagaimana kita merepresentasikan tanda petik tunggal di dalam string? Seperti ditunjukkan oleh contoh berikut ini, kita menulis dua tanda petik tunggal, yang mana tidak sama dengan jika kita menulis satu tanda petik ganda:

'Don''t leave without saving your work.'

PL/SQL adalah case sensitive di dalam literal-literal string. Sebagai contoh, PL/SQL menganggap literal-literal berikut ini berbeda satu sama lain:

'baker'
'Baker'

2.2.3.4. Boolean Literals

Literal boolean merupakan nilai predefined TRUE, FALSE, dan NULL (yang berarti nilai yang hilang, tidak diketahui, atau tidak dapat diaplikasikan). Harap diingat, literal-literal Boolean merupakan sebuah nilai, bukan string. Sebagai contoh, NULL bernilai tidak kurang dari angka 25.

2.2.3.5. Datetime Literals

Literal-literal datetime (tanggal dan waktu) memiliki banyak bentuk bergantung kepada tipe datanya. Sebagai contoh:

DECLARE
d1 DATE := DATE '1998-12-25';
t1 TIMESTAMP := TIMESTAMP '1997-10-22 13:01:01';
t2 TIMESTAMP WITH TIME ZONE := TIMESTAMP '1997-01-31 09:26:56.66+02:00';
-- Tiga tahun dan dua bulan
-- (Untuk presisi yang lebih besar, kita menggunakan day-to-second interval)
i1 INTERVAL YEAR TO MONTH := INTERVAL '3-2' YEAR TO MONTH;
-- Five days, four hours, three minutes, two and 1/100 seconds
i2 INTERVAL DAY TO SECOND := INTERVAL '5 04:03:02.01' DAY TO SECOND;
...

Kita dapat juga menentukan apakah interval yang dibelikan adalah YEAR TO MONTH atau DAY TO SECOND. Sebagai contoh, current_timestamp – current_timestamp secara default akan menghasilkan nilai bertipe INTERVAL DAY TO SECOND. Kita dapat menentukan tipe interval dengan menggunakan bentuk-bentuk:

2.2.4. Comments

PL/SQL compiler mengabaikan komentar-komentar, tetapi sebaiknya kita tidak. Menambahkan komentar pada program kita meningkatkan kemampuan pembacaan program dan membantu kita dalam mengerti alur sebuah program. Secara umum, kita menggunakan komentar-komentar untuk mendeskripsikan tujuan dan penggunaan dari setiap bagian program. PL/SQL mendukung dua bentuk komentar: single-line dan multi-line.

2.2.4.1. Single-Line Comments

Single-line comments diawali dengan tanda penghubung ganda (–) dimanapun dalam garis dan hingga akhir baris. Beberapa contohnya adalah sebagai berikut:

-- pemrosesan dimulai
SELECT sal INTO salary FROM emp -- mendapatkan gaji terakhir
WHERE empno = emp_id;
bonus := salary * 0.15; -- menghitung total bonus

Perlu dicatat bahwa komentar-komentar dapat tampak di dalam perintah pada akhir baris.

Ketika kita mengetes dan men-debug program, kita mungkin ingin men-disable baris kode program. Contoh berikut ini menunjukkan bagaimana kita dapat membuat baris menjadi komentar:

-- DELETE FROM emp WHERE comm IS NULL;

2.2.4.2. Multi-line Comments

Multi-line comments diawali dengan slash-asterisk (/*), diakhiri dengan asterisk-slash (*/), dan dapat berupa beberapa baris. Beberapa contohnya adalah:

BEGIN
  ...
  /* Menghitung bonus 15% untuk karyawan dengan rating tertinggi. */
  IF rating > 90 THEN
    bonus := salary * 0.15 /* bonus berdasarkan gaji */
  ELSE
    bonus := 0;
  END IF;
  ...
  /* Baris berikut ini menghitung luas lingkaran menggunan pi,
  yang mana merupakan area antara lingkar dan diameter. */

  area := pi * radius**2;
END;

Kita dapat menggunakan multi-line comment delimiters untuk mengubah seluruh bagian program menjadi komentar, seperti ditunjukkan oleh contoh berikut ini:

/*
LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
...
END LOOP;
*/

2.2.4.3. Batasan-batasan Comments

Kita tidak dapat menyarangkan komentar-komentar. Juga, kita tidak dapat menggunakan single-line comments di dalam blok PL/SQL yang akan diproses secara dinamis oleh program Oracle Precompiler karena end-of-line characters akan diabaikan. Sebagai hasilnya, single-line comments menjangkau hingga akhir blok, tidak hanya hingga akhir baris. Sehingga, lebih baik kita menggunakan multi-line comments.

2.3. Declarations

Program yang kita buat menyimpan nilai-nilai di dalam variable dan konstanta. Ketika program dieksekusi, nilai variable dapat berubah, sedangkan nilai konstanta tetap.

Kita dapat mendeklarasikan variable dan konstanta di dalam bagian declarative pada setiap blok PL/SQL, subprogram, atau package. Deklarasi mengalokasikan space penyimpanan untuk nilai, menentukan tipe datanya, dan menamai lokasi penyimpanan sehingga kita dapat mereferensi terhadapnya. Beberapa contohnya adalah sebagai berikut:

birthday DATE;
emp_count SMALLINT := 0;

Deklarasi pertama menamai variable dengan tipe DATE. Deklarasi kedua menamai variable dengan tipe SMALLINT dan menggunakan assignment operator untuk memberikan nilai inisial nol untuk variable.

Contoh-contoh berikut ini menunjukkan bahwa ekspresi yang mengikuti assignment operator dapat menjadi keputusan yang kompleks dan dapat merefer kepada variable yang telah diinisialisasi sebelumnya:

pi REAL := 3.14159;
radius REAL := 1;
area REAL := pi * radius**2;

Secara default, variable diinisialisasi dengan nilai NULL. Sehingga, deklarasi-deklarasi berikut ini adlaah sama:

birthday DATE;
birthday DATE := NULL;

Pada deklarasi konstanta, keyword CONSTANT harus diletakkan sebelum tipe data, seperti ditunjukkan oleh contoh berikut ini:

credit_limit CONSTANT REAL := 5000.00;

Deklarasi ini menamai konstanta dengan tipe REAL dan memberikan nilai awal (yang juga merupakan nilai akhir) 5000. Konstanta harus diinisialisasi pada saat pendeklarasiannya. Jika tidak, kita akan mendapatkan pesan kesalahan ketika deklarasi dielaborasi. (Pemrosesan deklarasi oleh PL/SQL compiler disebut dengan elaboration).

2.3.1. Menggunakan DEFAULT

Kita dapat menggunakan keyword DEFAULT dibandingkan dengan menggunakan assignment operator untuk menginisialisasi variable. Sebagai contoh, deklarasi

blood_type CHAR := 'O';

dapat ditulis kembali menjadi:

blood_type CHAR DEFAULT 'O';

Gunakan DEFAULT untuk variable-variable yang memiliki nilai khusus. Gunakan assignment operator untuk variable-variable (seperti counter dan akumulator) yang tidak memiliki nilai khusus. Beberapa contohnya adalah:

hours_worked INTEGER DEFAULT 40;
employee_count INTEGER := 0;

Kita dapat juga menggunakan DEFAULT untuk menginisialisasi parameter-parameter subprogram, parameter-parameter cursor, dan field-field dalam user-defined record.

2.3.2. Menggunakan NOT NULL

Disamping memberikan nilai awal, deklarasi dapat menentukan constraint NOT NULL, seperti ditunjukkan oleh contoh berikut:

acct_id INTEGER(4) NOT NULL := 9999;

Kita tidak dapat memberikan nilai null kepada variable yang telah didefinisikan sebagai NOT NULL. Jika kita mencobanya, PL/SQL akan menampilkan predefined exception VALUE_ERROR. Constraint NOT NULL harus diikuti oleh klausa inisialisasi. Sebagai contoh, deklarasi berikut ini tidak diperbolehkan:

acct_id INTEGER(5) NOT NULL; -- tidak diperbolehkan; tidak diinisialisasi

Dalam deklarasi NATURALN dan POSITIVEN, penentu tipe (type specifier) harus diikuti oleh klausa inisialisasi. Jika tidak, kita akan mendapatkan pesan kesalahan. Sebagai contoh, deklarasi berikut ini tidak diperbolehkan:

line_items POSITIVEN; -- tidak diperbolehkan; tidak diinisialisasi

2.3.3. Menggunakan %TYPE

Attribute %TYPE menyediakan tipe data untuk variable dan database column. Dalam contoh berikut, %TYPE menyediakan tipe data dari variable:

credit REAL(7,2);
debit credit%TYPE;

Variable-variable yang dideklarasikan menggunakan %TYPE diperlakukan seperti variable-variable yang dideklarasikan menggunakan datatype specifier. Sebagai contoh, pada deklarasi sebelumnya, PL/SQL memperlakukan debit seperti variable bertipe data REAL(7,2). Contoh berikut ini menunjukkan bahwa deklarasi %TYPE dapat mengandung klausa inisialisasi:

balance NUMBER(7,2);
minimum_balance balance%TYPE := 10.00;

Attribute %TYPE terutama sekali berguna ketika mendeklarasikan variable-variable yang mengacu kepada database column. Kita dapat mereferensi table dan column, atau kita dapat mereferensi owner, table, dan column, seperti pada contoh ini

my_dname scott.dept.dname%TYPE;

Menggunakan %TYPE untuk mendeklarasikan my_dname memiliki dua keuntungan. Pertama, tidak tidak perlu tahu tipe data sesungguhnya dari dname. Kedua, jika definisi database untuk dname berubah, tipe data my_dname berubah mengikuti perubahan dname.

Namun, variable-variable %TYPE tidak mewarisi constraint NOT NULL dari column yang diacunya. Dalam contoh berikutnya, meskipun database column empno didefinisikan sebagai NOT NULL, kita dapat memberikan nilai null kepada variable my_empno:

DECLARE
my_empno emp.empno%TYPE;
...
BEGIN
  my_empno := NULL; -- hal ini diperbolehkan dan dapat bekerja

2.3.4. Menggunakan %ROWTYPE

Attribute %ROWTYPE menyediakan tipe record yang merepresentasikan row (baris data) dalam table (atau view). Record dapat menyimpan seluruh baris data yang dipilih dari table atau dihasilkan dari cursor atau variable bertipe cursor. Dalam contoh berikut, kita mendeklarasikan dua record. Record pertama menyimpan baris data yang diambil dari table emp. Record kedua menyimpan baris data yang dihasilkan dari cursor c1.

DECLARE
emp_rec emp%ROWTYPE;
CURSOR c1 IS SELECT deptno, dname, loc FROM dept;
dept_rec c1%ROWTYPE;

Kolom-kolom dalam baris data dan field-field terkait di dalam record memiliki nama dan tipe data yang sama. Namun, field-field di dalam record %ROWTYPE tidak mewarisi constraint NOT NULL pada column.

Dalam contoh berikut ini, kita menampilkan nilai-nilai kolom ke dalam record emp_rec:

BEGIN
SELECT * INTO emp_rec FROM emp WHERE ...

Nilai-nilai column yang dihasilkan oleh perintah SELECT disimpan pada field-field. Untuk merefer field, kita menggunakan dot notation (.). Sebagai contoh, kita dapat merefer field deptno dengan cara berikut:

IF emp_rec.deptno = 20 THEN ...

Kita juga dapat memberikan nilai dari ekspresi kepada field tertentu, seperti contoh berikut ini:

emp_rec.ename := 'JOHNSON';
emp_rec.sal := emp_rec.sal * 1.15;

Pada contoh terakhir berikut ini, kita menggunakan %ROWTYPE untuk mendefinisikan packaged cursor:

CREATE PACKAGE emp_actions AS
CURSOR c1 RETURN emp%ROWTYPE; -- declare cursor specification
...
END emp_actions;
CREATE PACKAGE BODY emp_actions AS
CURSOR c1 RETURN emp%ROWTYPE IS -- define cursor body
SELECT * FROM emp WHERE sal > 3000;
...
END emp_actions;

2.3.4.1. Aggregate Assignment

Deklarasi %ROWTYPE tidak dapat mengandung klausa inisialisasi. Namun, ada dua jalan untuk memberikan nilai-nilai ke seluruh field-field di dalam record sekali. Pertama, PL/SQL mengijinkan aggregate assignment diantara seluruh record-record jika deklarasi mereka merefer kepada table atau cursor yang sama. Sebagai contoh, proses pemberian nilai berikut ini diperbolehkan:

DECLARE
  dept_rec1 dept%ROWTYPE;
  dept_rec2 dept%ROWTYPE;

  CURSOR c1 IS SELECT deptno, dname, loc FROM dept;
    dept_rec3 c1%ROWTYPE;
BEGIN
  ...
  dept_rec1 := dept_rec2;

Namun, karena dept_rec2 berbasiskan pada table dan dept_rec3 berbasiskan kepada cursor, assignment berikut ini tidak diperbolehkan:

dept_rec2 := dept_rec3; -- tidak diperbolehkan

Kedua, kita dapat memberikan nilai dari suatu daftar column kepada record dengan menggunakan perintah SELECT atau FETCH, seperti ditunjukkan oleh contoh berikut ini. Nama-nama column harus tampak pada urutan dimana mereka didefinisikan oleh perintah CREATE TABLE atau CREATE VIEW.

DECLARE
  dept_rec dept%ROWTYPE;
  ...
BEGIN
  SELECT * INTO dept_rec FROM dept WHERE deptno = 30;
  ...
END;

Namun, kita tidak dapat memberikan memberikan nilai kumpulan kolom kepada record dengan menggunakan perintah assignment. Jadi, sintaks berikut ini tidak diperbolehkan:

record_name := (value1, value2, value3, ...); -- tidak diperbolehkan

2.3.4.2. Menggunakan Aliases

Kumpulan item-item hasil dari cursor yang terasosiasi dengan %ROWTYPE harus memiliki nama yang sederhana, atau jika mereka adalah ekspresi, harus memiliki alias. Pada contoh berikut ini, kita menggunakan alias yang disebut wages:

DECLARE
  CURSOR my_cursor IS
    SELECT sal + NVL(comm, 0) wages, ename FROM emp;
    my_rec my_cursor%ROWTYPE;
BEGIN
  OPEN my_cursor;
  LOOP
    FETCH my_cursor INTO my_rec;
    EXIT WHEN my_cursor%NOTFOUND;
    IF my_rec.wages > 2000 THEN
      INSERT INTO temp VALUES (NULL, my_rec.wages, my_rec.ename);
    END IF;
  END LOOP;
  CLOSE my_cursor;
END;

2.3.5. Batasan-batasan Declarations

PL/SQL tidak memperbolehkan referensi kedepan (forward references). Kita harus mendeklarasikan variable atau konstanta sebelum menggunakannya pada perintah-perintah yang lain, termasuk perintah-perintah declarative lainnya. Sebagai contoh, deklarasi maxi berikut ini tidak diperbolehkan:

maxi INTEGER := 2 * mini; -- tidak diperbolehkan
mini INTEGER := 15;

Namun, PL/SQL tidak memperbolehkan forward declaration dari subprogram.

Beberapa bahasa mengijinkan kita untuk mendeklarasikan daftar variable-variable yang memiliki tipe data yang sama. PL/SQL tidak mengijinkan hal ini. Sebagai contoh, deklarasi berikut ini tidak diperbolehkan:

i, j, k SMALLINT; -- tidak diperbolehkan

Kita harus mendeklarasikan setiap variable secara terpisah:

i SMALLINT;
j SMALLINT;
k SMALLINT;

2.4. PL/SQL Naming Conventions

Ketentuan penamaan yang sama berlaku untuk seluruh item-item dan unit-unit program PL/SQL termasuk konstanta, variable, cursor, cursor variable, exception, procedure, function, dan package. Nama dapat sederhana, memenuhi syarat, dari tempat lain, atau keduanya. Sebagai contoh, kita mungkin menggunakan procedure raise_salary dengan berbagai cara berikut:

raise_salary(...); -- simple
emp_actions.raise_salary(...); -- qualified
raise_salary@newyork(...); -- remote
emp_actions.raise_salary@newyork(...); -- qualified and remote

Pada kasus pertama, kita secara sederhana menggunakan nama procedure. Kasus kedua, kita harus menentukan nama menggunakan dot notation karena procedure diletakkan di dalam package bernama emp_actions. Pada kasus ketiga, menggunakan remote access indicator (@), kita merefer database link newyork karena procedure terletak pada remote database. Sedangkan pada kasus keempat, kita mengguankan nama procedure dan merefer database link.

2.4.1. Synonyms

Kita dapat menciptakan synonym untuk menyediakan transparansi terhadap remote schema objects seperti table, sequence, view, standalone subprogram, package, dan object type. Namun, kita tidak dapat menciptakan synonym untuk item-item yang dideklarasikan di dalam subprogram atau package. Termasuk konstanta, variable, cursor, cursor variable, exception, dan subprogram ter-package.

2.4.2. Scoping

Didalam jangkauan yang sama, seluruh identifier yang dideklarasikan harus unik. Sehingga, meskipun tipe-tipe data mereka berbeda, variable-variable dan parameter-parameter tidak dapat berbagi nama yang sama. Pada contoh berikut ini, deklarasi kedua tidak diperbolehkan:

DECLARE
valid_id BOOLEAN;
valid_id VARCHAR2(5); -- tidak diperbolehkan adanya duplicate identifier

2.4.3. Case Sensitivity

Seperti hanya seluruh identifier, nama dari konstanta, variable, dan parameter tidak case-sensitive. Sebagai contoh, PL/SQL mengganggap nama-nama berikut adalah sama:

DECLARE
zip_code INTEGER;
Zip_Code INTEGER; -- same as zip_code

2.4.4. Name Resolution

Dalam kemungkinan adanya kerancuan perintah-perintah SQL, nama-nama kolom database memiliki hak lebih tinggi diatas nama-nama variable lokal dan parameter-parameter formal. Sebagai contoh, perintah DELETE berikut ini menghapus seluruh karyawan dari table emp, tidak hanya ‘KING’, karena Oracle mengasumsikan bahwa kedua enames di dalam klausa WHERE mengacu kepada kolom di database:

DECLARE
  ename VARCHAR2(10) := 'KING';
BEGIN
  DELETE FROM emp WHERE ename = ename;
  ...

Pada kasus seperti ini, untuk menghindari kerancuan, awali nama-nama dari variable lokal dan parameter-parameter format dengan my_. seperti contoh berikut ini:

DECLARE
my_ename VARCHAR2(10);

Atau, gunakan label blok untuk mengkualifikasi referensi, seperti dalam

<<main>>
DECLARE
ename VARCHAR2(10) := 'KING';
BEGIN
DELETE FROM emp WHERE ename = main.ename;

Contoh berikutnya menunjukkan bahwa kita dapat menggunakan nama subprogram untuk mengkualifikasi referensi ke variable-variable lokal dan parameter-parameter formal:

FUNCTION bonus (deptno IN NUMBER, ...) RETURN REAL IS
  job CHAR(10);
BEGIN
  SELECT ... WHERE deptno = bonus.deptno AND job = bonus.job;

2.5. Scope dan Visibility dari PL/SQL Indentifiers

Referensi kepada identifier ditetapkan berdasarkan jangkauan dan jarak pandang. Scope dari identifier adalah pada daerah program unit (blok, subprogram, atau package) dari mana kita dapat mereferensi terhadap identifier tersebut. Identifier visible / tampak hanya di dalam daerah-daerah dari mana kita dapat mereferensi identifier tersebut menggunakan nama yang tidak terkualifikasi. Gambar 2-1 menunjukkan jangkauan dan jarak pandang dari variable bernama x, yang dideklarasikan di dalam blok yang menutupnya, lalu dideklarasikan ulang di dalam sub-blok.

Identifier-identifier yang dideklarasikan di dalam blok PL/SQL dianggap lokal terhadap blok dan global terhadap sub-blok-nya. Jika identifier global dideklarasikan ulang di dalam sub-blok, kedua identifier-identifier tersebut tetap di dalam jangkauan. Menyertai sub-blok, bagaimanapun juga, hanya identifier lokal yang terlihat, karena kita harus menggunakan nama yang terkualifikasi untuk merefer kepada identifier global.

Meskipun kita tidak dapat mendeklarasikan identifier dua kali di dalam blok yang sama, kita dapat mendeklarasikan identifier yang dama di dalam dua blok yang berbeda. Dua item yang direpresentasikan oleh identifier adalah berbeda, dan perubahan yang terjadi pada salah satunya tidak mempengaruhi yang lain. Namun, blok tidak dapat merefer identifier-identifier yang dideklarasikan di dalam blok-blok yang lain pada level yang sama karena identifier-identifier tersebut tidak lokal dan tidak juga global terhadap blok tersebut.

Gambar 2.1. Scope dan Visibility

Contoh berikut ini menggambarkan aturan-aturan jangkauan. Perlu diingat bahwa identifier-identifier yang dideklarasikan di dalam satu sub-blok tidak dapat direferensi atau digunakan di dalam sub-blok yang lain. Hal ini dikarenakan blok tidak dapat menggunakan atau mereferensi identifier-identifier di dalam blok-blok lain pada level yang sama.

DECLARE
  a CHAR;
  b REAL;
BEGIN
  -- identifiers tersedia disini: a (CHAR), b
  DECLARE
    a INTEGER;
    c REAL;
  BEGIN
    -- identifiers tersedia disini: a (INTEGER), b, c
  END;
  DECLARE
    d REAL;
  BEGIN
    -- identifiers tersedia disini: a (CHAR), b, d
  END;
  -- identifiers tersedia disini: a (CHAR), b
END;

Pemanggilan kembali terhadap identifier-identifier global tersebut dapat dideklarasikan ulang di dalam sub-blok, yang pada akhirnya deklarasi lokal berlaku dan sub-blok tidak dapat mereferensi identifier global kecuali kita menggunakan nama yang terkualifikasi. Pengkualifikasi dapat berupa label dari blok yang menyertainya, seperti ditunjukkan oleh contoh berikut ini:

<<outer>>
DECLARE
  birthdate DATE;
BEGIN
  DECLARE
    birthdate DATE;
  BEGIN
    ...
    IF birthdate = outer.birthdate THEN ...
  END;
  ...
END;

Seperti ditunjukkan oleh contoh berikut ini, pengkualifikasi dapat juga berupa nama dari subprogram yang mengapitnya:

PROCEDURE check_credit (...) IS
  rating NUMBER;
FUNCTION valid (...) RETURN BOOLEAN IS
  rating NUMBER;
BEGIN
  ...
  IF check_credit.rating < 3 THEN ...
  END;
  BEGIN
  ...
  END;

Namun, di dalam jangkauan yang sama, label dan subprogram tidak dapat memiliki nama yang sama.

Oracle MagazineOracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world’s largest enterprise software company.

For more information about Oracle, please visit their Web site at http://www.oracle.com. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Get Free Oracle Magazine

2.6. Variable Assignment

Variable dan konstanta diinisialisasi setiap saat blok atau subprogram diinputkan. Secara default, variable diberi nilai awal NULL. Kecuali kita secara langsung memberikan nilai awal terhadap variable tersebut, nilainya tidak didefinisikan:

DECLARE
  count INTEGER;
BEGIN
-- COUNT dimulai dengan nilai NULL.
-- Sehingga ekspresi 'COUNT + 1' juga null.
-- Lalu setelah pemberian nilai ini, COUNT tetap NULL.
count := count + 1;

Untuk menghindari hasil-hasil yang tidak diharapkan, jangan pernah mereferensi ke variable sebelum kita memberikan nilai kepadanya.
Kita dapat menggunakan perintah-perintah assignment untuk memberikan nilai ke variable. Sebagai contoh, perintah berikut ini memberikan nilai baru ke variable bonus, dan menimpa nilai lamanya:

bonus := salary * 0.15;

Ekspresi yang mengikuti operator assignment dapat menjadi kompleks, tetapi ia harus menghasilkan tipe data yang sama dengan atau dapat dikonversi ke tipe data dari variable.

2.6.1. Assigning Boolean Values

Hanya nilai-nilai TRUE, FALSE, dan NULL yang dapt diberikan ke variable bertipe Boolean. Sebagai contoh, deklarasi berikut ini

DECLARE
done BOOLEAN;

perintah-perintah berikut ini diperbolehkan:

BEGIN
  done := FALSE;
WHILE NOT done LOOP
  ...
END LOOP;

Ketika diaplikasikan ke ekspresi, operator-operator relasional menghasilkan nilai Boolean. Sehingga pemberikan nilai berikut ini diperbolehkan:

done := (count > 500);

2.6.2. Assigning SQL Query Result to a PL/SQL Variable

Kita dapat menggunakan perintah SELECT untuk mengharuskan Oracle memberikan nilai-nilai ke variable. Untuk setiap item di dalam daftar select, mereka harus berkaitan, variable type-compatible di dalam INTO. Contohnya adalah sebagai berikut:

DECLARE
  emp_id emp.empno%TYPE;
  emp_name emp.ename%TYPE;
  wages NUMBER(7,2);
BEGIN
  -- memberikan nilai terhadap emp_id disini
  SELECT ename, sal + comm
  INTO emp_name, wages FROM emp
  WHERE empno = emp_id;
  ...
END;

Namun, kita tidak dapat menampilkan nilai-nilai kolom ke variable Boolean.

2.7. PL/SQL Expression and Comparisons

Ekspresi dibangun dengan menggunakan operand dan operator. Operand adalah variable, konstanta, literal, atau function call yang menambah nilai terhadap ekspresi. Contoh dari ekspresi aritmatika sederhana adalah sebagai berikut:

- X / 2 + 3

Operator-operator unary seperti negation operator (-) beroperasi pada satu operand; operator-operator binary seperti division operator (/) beroperasi pada dua operand. PL/SQL tidak memiliki operator-operator ternary.

Ekspresi-ekspresi paling sederhana terdiri dari variable tunggal, yang menghasilkan nilai secara langsung. PL/SQL mengevaluasi (menemukan nilai terkini dari) ekspresi dengan mengkombinasikan nilai-nilai dari operand dengan jalan yang ditentukan oleh operator-operator. Hal ini selalu menghasilkan nilai dan tipe data tunggal. PL/SQL menentukan tipe data dengan memeriksa ekspresi dan konteks dimana ia muncul.

Operator Precedence

Operasi-operasi di dalam ekspresi terjadi dalam perintah khusus bergantung kepada prioritasnya. Table 2-1 menunjukkan perintah default dari operasi-operasi dari awal sampai akhir (dari atas ke bawah).

Table 2-1 Urutan operasi

Operator-operator dengan prioritas lebih tinggi diaplikasikan pertama. Di dalam contoh di bawah ini, kedua ekspresi menghasilkan 8 karena pembagian memiliki prioritas lebih tinggi dibandingkan penjumlahan. Operator-operator dengan prioritas yang sama diaplikasikan di dalam urutan khusus.

5 + 12 / 4
12 / 4 + 5

Kita dapat menggunakan tanda kurung untuk mengontrol urutan evaluasi. Sebagai contoh, ekspresi berikut ini menghasilkan 7, bukan 11, karena tanda kurung mengesampingkan urutan prioritas default:

(8 + 6) / 2

Pada contoh berikutnya, pengurangan di dilakukan sebelum pembagian karena sub-ekspresi yang paling dalam selalu dievaluasi pertama kali:

100 + (20 / 5 + (7 - 3))

Contoh berikut ini menunjukkan bahwa kita dapat selalu menggunakan tanda-tanda kurung untuk meningkatkan keterbacaan, bahkan ketika mereka tidak diperlukan:

(salary * 0.05) + (commission * 0.25)

2.7.1. Logical Operators

Operator-operator logikal AND, OR, dan NOT mengikuti logika tiga keadaan yang ditunjukkan dalam Table 2-2. AND dan OR adalah operator-operator binary; sedangkan NOT adalah operator unary.

Table 2-2. Table Kebenaran

Seperti ditunjukkan oleh table kebenaran, AND menghasilkan TRUE hanya jika kedua operand-nya bernilai true. Sedangkan OR menghasilkan TRUE jika salah satu dari operand-nya bernilai true.  NOT menghasilkan nilai kebalikan (negasi logikal) dari operand-nya. Sebagai contoh, NOT TRUE menghasilkan FALSE.

NOT NULL menghasilkan NULL karena null tidak dapat ditentukan.Bahkan jika kita mengaplikasikan operator NOT terhadap null, hasilnya juga tidak dapat ditentukan. Kita harus berhati-hati. Null dapat menyebabkan nilai-nilai yang tidak diharapkan.

2.7.1.1. Order or Evaluation

Ketika kita tidak menggunakan tanda kurung untuk menentukan urutan evaluasi, prioritas operator ditentukan oleh urutannya. Bandingkan ekspresi-ekspresi berikut ini:

NOT (valid AND done)    |    NOT valid AND done

Jika variable-variable Boolean valid dan done memiliki nilai FALSE, ekspresi pertama menghasilkan TRUE. Namun, ekspresi kedua menghasilkan FALSE because NOT memiliki prioritas lebih tinggi dibandingkan AND. Dengan demikian, ekspresi kedua sama dengan:

(NOT valid) AND done

Di dalam contoh berikut ini, perlu diingat bahwa ketika valid memiliki nilai FALSE, seluruh ekspresi menghasilkan FALSE tanpa memperhatikan nilai dari done.

valid AND done

Serupa dengan kasus diatas, dalam contoh berikut ini, ketika valid memiliki nilai TRUE, seluruh ekspresi menghasilkan TRUE tanpa memperhatikan nilai done:

valid OR done

2.7.1.2. Short-Circuit Evaluation

Ketika mengevaluasi ekspresi logika, PL/SQL menggunakan short-circuit evaluation. Jadi, PL/SQL menghentikan mengevaluasi ekspresi segera setelah hasilnya dapat ditentukan. Hal ini mengijinkan kita menulis ekspresi-ekspresi yang mungkin sebaliknya menyebabkan kesalahan. Perhatikan ekspresi OR berikut ini:

DECLARE
  ...
  on_hand INTEGER;
  on_order INTEGER;
BEGIN
  ..
  IF (on_hand = 0) OR ((on_order / on_hand) < 5) THEN
    ...
  END IF;
END;

Ketika nilai dari on_hand adalah nol, operand sebelah kiri menghasilkan TRUE, sehingga PL/SQL tidak perlu mengevaluasi operand kanan. Jika PL/SQL mengevaluasi kedua operand sebelum menerapkan operator OR, operand kanan akan menyebabkan error division by zero. Dalam beberapa kasus, merupakan praktek pemrograman yang buruk untuk mempercayakan pada evaluasi short-circuit.

2.7.1.3. Comparison Operators

Operator pembanding membandingkan satu ekspresi dengan lainnya. Hasilnya selalu true, false, atau null. Biasanya, kita menggunakan operator-operator pembanding di dalam perintah-perintah pengontrol kondisi di dalam klausa WHERE dari perintah-perintah manipulasi data SQL. Berikut ini beberapa contohnya:

IF quantity_on_hand > 0 THEN
  UPDATE inventory
  SET quantity = quantity - 1
  WHERE part_number = item_number;
ELSE
  ...
END IF;

2.7.1.4. Relational Operators

Operator-operator relasional mengijinkan kita untuk membandingkan ekspresi-ekspresi kompleks. Daftar berikut ini menunjukkan arti dari setiap operator:

= sama dengan
<>, !=, ~=, ^= tidak sama dengan
< lebih kecil dari
> lebih besar dari
<= lebih kecil dari atau sama dengan
>= lebih besar dari atau sama dengan

2.7.1.5. IS NULL Operator

Operator IS NULL menghasilkan nilai Boolean TRUE jika operand-nya null atau FALSE jika ia bukan null. Perbandingan-perbandingan yang melibatkan null selalu menghasilkan NULL. Sehingga, selalu lakukan pengecekan, seperti berikut:

IF variable IS NULL THEN ...

2.7.1.6. LIKE Operator

Kita menggunakan operator LIKE untuk membandingkan nilai karakter, string, atau CLOB dengan sebuah pola. LIKE menghasilkan nilai Boolean TRUE jika pola-polanya sesuai atau FALSE jika tidak.

Pola-pola yang disesuaikan oleh LIKE dapat mengandung dua karakter bertujuan khusus yang disebut dengan wildcards. Tanda garis bawah (_) menyamakan secara tepat satu karakter; tanda persen (%) menyamakan nol atau lebih karakter. Sebagai contoh, jika nilai ename adalah ‘JOHNSON’, ekspresi berikut ini adalah benar:

ename LIKE 'J%SON'

2.7.1.7. BETWEEN Operator

Operator BETWEEN mengetes apakah suatu nilai berada dalam jangkauan yang telah ditetapkan. Hal ini berarti ”lebih besar dari atau sama dengan nilai rendah dan kurang dari atau sama dengan nilai tinggi”. Sebagai contoh, ekspresi berikut ini salah:

45 BETWEEN 38 AND 44

2.7.1.8. IN Operator

Operator IN memeriksa kumpulan keanggotaan. Hal ini berarti “sama dengan beberapa anggota dari.” Kumpulan tersebut dapat mengandung nilai-nilai null, tetapi mereka diabaikan. Sebagai contoh, perintah berikut tidak menghapus baris-baris dimana kolom ename adalah null:

DELETE FROM emp WHERE ename IN (NULL, 'KING', 'FORD');

Selanjutnya, ekspresi dari bentuk

value NOT IN set

menghasilkan FALSE jika set mengandung null. Sebagai contoh, bukannya menghapus baris di mana kolom ename tidak null dan tidak ‘KING’ , perintah berikut tidak menghapus apa-apa:

DELETE FROM emp WHERE ename NOT IN (NULL, 'KING');

2.7.1.9. Concatenation Operator

Garis vertikal ganda (||) berlaku sebagai operator penggabungan, yang menambahkan satu string (CHAR, VARCHAR2, CLOB, atau tipe Unicode-enabled yang serupa) kepada lainnya. Sebagai contoh, ekspresi

'suit' || 'case'

Menghasilkan nilai berikut:

'suitcase'

Jika kedua operand memiliki tipe data CHAR, operator penggabungan menghasilkan nilai CHAR. Jika salah satu operand bernilai CLOB, operator menghasilkan CLOB sementara (temporary CLOB). Sebaliknya, operator menghasilkan nilai VARCHAR2.

2.7.2. Boolean Expressions

PL/SQL mengijinkan kita untuk membandingkan variable-variable dan konstanta-konstanta baik melalui SQL maupun melalui perintah-perintah prosedural. Perbandingan-perbandingan ini, yang disebut Boolean expressions, terdiri dari ekspresi-ekspresi sederhana atau  kompleks yang dipisahkan oleh operator-operator relasional. Seringkali, ekspresi-ekspresi Boolean dihubungkan oleh operator-operator logikal AND, OR, dan NOT. Ekspresi Boolean selalu menghasilkan TRUE, FALSE, dan NULL.

Dalam perintah SQL, ekspresi-ekspresi Boolean mengijinkan kita menentukan baris-baris data di dalam table yang terpengaruh oleh perintah tersebut. Dalam perintah prosedural, ekspresi-ekspresi Boolean merupakan dasar untuk pengontrol kondisional. Terdapat tiga jenis ekspresi-ekspresi Boolean: aritmatika, karakter, dan tanggal.

2.7.2.1. Boolean Arithmetic Expressions

Kita dapat membandingkan nilai-nilai karakter untuk persamaan dan pertidaksamaan. Secara default, perbandingan-perbandingan didasarkan pada nilai-nilai binary dari setiap byte dalam string. Sebagai contoh, beberapa proses pemberian nilai berikut ini

string1 := 'Kathy';
string2 := 'Kathleen';

ekspresi berikut ini adalah benar

string1 > string2

Dengan mengatur initialization parameter NLS_COMP=ANSI, kita dapat membuat perbandingan-perbandingan menggunakan collating sequence oleh initialization parameter NLS_SORT. Collating sequence merupakan urutan internal dari character set dimana jangkauan kode-kode numerik merepresentasikan karakter-karakter individual. Sebuah nilai karakter lebih besar daripada lainnya jika numerik internalnya lebih besar. Setiap bahasa pemrograman bisa memiliki aturan-aturan yang berbeda mengenai dimana karakter-karakter tersebut tampak di dalam collating sequence. Sebagai contoh, huruf beraksen mungkin diurutkan secara berbeda bergantung character set dari database, meskipun nilai binary-nya sama dalam setiap kasus.

Terdapat perbedaan semantik (arti kata) antara tipe-tipe dasar CHAR dan VARCHAR2 yang datang ketika kita membandingkan nilai-nilai karakter.
Banyak tipe-tipe yang dapat dikonversi menjadi tipe-tipe karakter. Sebagai contoh, kita dapat membandingkan, memberikan nilai, dan melakukan operasi-operasi karakter lainnya dengan menggunakan variable-variable CLOB.

2.7.2.2. Boolean Date Expressions
Kita dapat pula membandingkan tanggal. Perbandingan-perbandingan adalah kronologis: jadi, satu tanggal lebih besar daripada lainnya jika ia lebih baru (lebih terkini). Sebagai contoh, pemberian-pemberian nilai ini

date1 := '01-JAN-91';
date2 := '31-DEC-90';

ekspresi berikut ini adalah benar:

date1 > date2

2.7.2.3. Aturan untuk PL/SQL Boolean Expressions

count := 1;
IF count = 1.0 THEN
  ...
END IF;
100 < tax < 500 -- not allowed

Versi debug-nya adalah sebagai berikut

(100 < tax) AND (tax < 500)
WHILE NOT (done = TRUE) LOOP
...
END LOOP;

dapat disederhanakan sebagai berikut

WHILE NOT done LOOP
...
END LOOP;

2.7.3. CASE Expressions
Ekspresi CASE mendapatkan hasil dari satu atau dua alternatif, dan menghasilkan hasil. Ekspresi CASE menggunakan selector, dan ekspresi yang nilainya menentukan alternatif mana yang dikembalikan. Ekspresi CASE memiliki bentuk sebagai berikut:

CASE selector   WHEN expression1 THEN result1   WHEN expression2 THEN result2
  ...
  WHEN expressionN THEN resultN
  [ELSE resultN+1]
END;

Penyeleksi diikuti oleh satu atau lebih klausa WHERE, yang dicek secara berurutan. Nilai dari penyeleksi menentukan klausa mana yang dieksekusi. Klausa WHERE pertama yang sesuai dengan nilai dari penyeleksi menentukan nilai hasilnya, dan klausa WHERE berikutnya tidak lagi dievaluasi. Contohnya sebagai berikut:

DECLARE
  grade CHAR(1) := 'B';
  appraisal VARCHAR2(20);
BEGIN
  appraisal :=
  CASE grade
    WHEN 'A' THEN 'Excellent'
    WHEN 'B' THEN 'Very Good'
    WHEN 'C' THEN 'Good'
    WHEN 'D' THEN 'Fair'
    WHEN 'F' THEN 'Poor'
    ELSE 'No such grade’
  END;
END;

Klausa opsional ELSE bekerja mirip dengan klausa ELSE dalam perintah IF. Jika nilai dari penyeleksi tidak terdapat pada salah satu dari pilihan-pilihan yang disediakan oleh klausa WHEN, klausa ELSE dieksekusi. Jika tidak ada klausa ELSE yang disediakan dan tidak ada klausa WHEN yang cocok, maka ekspresi menghasilkan NULL.

Alternatif untuk ekspresi CASE adalah perintah CASE, dimana klausa WHEN dapat berupa seluruh blok PL/SQL.

2.7.3.1. Searched CASE Expression

PL/SQL juga menyediakan ekspresi CASE pencarian, yang memiliki bentuk:

CASE
  WHEN search_condition1 THEN result1
  WHEN search_condition2 THEN result2
  ...
  WHEN search_conditionN THEN resultN
  [ELSE resultN+1]
END;

Ekspresi CASE pencarian tidak memiliki penyeleksi. Setiap klausa WHEN mengandung kondisi pencarian yang menghasilkan nilai Boolean, yang mengijinkan kita untuk mengetes perbedaan variable-variable atau banyak kondisi di dalam klausa WHEN tunggal. Contohnya adalah sebagai berikut:

DECLARE
  grade CHAR(1);
  appraisal VARCHAR2(20);
BEGIN
  ...
  appraisal :=
    CASE
      WHEN grade = 'A' THEN 'Excellent'
      WHEN grade = 'B' THEN 'Very Good'
      WHEN grade = 'C' THEN 'Good'
      WHEN grade = 'D' THEN 'Fair'
      WHEN grade = 'F' THEN 'Poor'
      ELSE 'No such grade'
    END;
  ...
END;

Kondisi-kondisi pencarian dievaluasi secara berurutan. Nilai Boolean dari setiap kondisi pencarian menentukan dimana klausa WHEN dieksekusi. Jika kondisi pencarian menghasilkan TRUE, klausa WHEN-nya dieksekusi. Setelah satu klausa WHEN dieksekusi, kondisi-kondisi pencarian lainnya tidak dievaluasi, Jika tidak ada kondisi-kondisi pencarian yang menghasilkan TRUE, klausa opsional ELSE dieksekusi. Jika tidak ada klausa WHEN yang dieksekusi dan tidak ada klausa ELSE yang disediakan, nilai dari ekspresi adalah NULL.

2.7.4. Menangani Nilai-nilai Null dalam Perintah-perintah Perbandingan dan Kondisional

Ketika bekerja dengan null, kita dapat menghindari beberapa kesalahan-kesalahan umum dengan mengingat aturan-aturan berikut ini:

Dalam contoh beirkut ini, kita mungkin berharap perintah-perintah selanjutkan dieksekusi karena x dan y terlihat tidak sama. Namun, null memiliki tingkat menengak. Apakah x sama dengan y adalah tidak diketahui. Sehingga, kondisi IF menghasilkan NULL dan perintah-perintah selanjutnya akan dilewati (diabaikan).

x := 5;
y := NULL;
...
IF x != y THEN -- menghasilkan NULL, bukan TRUE
  sequence_of_statements; -- tidak dieksekusi
END IF;

Dalam contoh selanjutnya, kita mungkin berharap perintah-perintah dieksekusi karena a dan b terlihat sama. Namun, lagi, hal ini tidak diketahui, maka kondisi IF menghasilkan NULL dan perintah-perintah selanjutnya akan diabaikan.

a := NULL;
b := NULL;
...
IF a = b THEN -- menghasilkan NULL, bukan TRUE
  sequence_of_statements; -- tidak dieksekusi
END IF;

2.7.4.1. Operator NOT

Perlu diingat kembali bahwa penerapan operator logikal NOT terhadap null menghasilkan NULL. Sehingga, dua perintah-perintah dibawah ini tidak selalu sama:

IF x > y THEN    |   IF NOT x > y THEN
  high := x;     |     high := y;
ELSE             |   ELSE
  high := y;     |     high := x;
END IF;          |   END IF;

Perintah-perintah selanjutnya di dalam klausa ELSE dieksekusi ketika kondisi IF menghasilkan FALSE atau NULL. Jika tidak satupun x atau y merupakan null, ketua perintah IF memberikan nilai yang sama kepada high. Namun, jika salah satu x atau y adalah null, perintah IF yang pertama akan memberikan nilai y kepada high, tetapi perintah IF yang kedua akan memberikan nilai x kepada high.

2.7.4.2. Zero-Length Strings

PL/SQL memperlakukan string zero-length seperti null. Ini termasuk nilai-nilai yang dihasilkan oleh function-function karakter dan ekspresi-ekspresi Boolean. Sebagai contoh, perintah-perintah berikut memberikan null kepada variable-variable target:

null_string := TO_CHAR('');
zip_code := SUBSTR(address, 25, 0);
valid := (name != '');

Sehingga, gunakan operator IS NULL untuk mengetes string-string null, seperti berikut ini:

IF my_string IS NULL THEN ...

2.7.4.3. Concanetation Operator

Operator penggabungan mengabaikan operand-operand null. Sebagai contoh, ekspresi

'apple' || NULL || NULL || 'sauce'

menghasilkan nilai berikut ini:

'applesauce'

2.7.4.4. Functions

Jika argumen null dilewatkan kepada built-in function, null dihesilkan kecuali dalam kasus-kasus berikut.

Function DECODE membandingkan argumen pertamanya dengan satu atau lebih ekspresi-ekspresi pencarian, yang berpasangan dengan ekspresi-ekspresi hasil. Beberapa ekspresi pencarian atau hasil dapat berupa null. Jika pencarian berhasil, hasil yang sesuai dikembalikan. Dalam contoh berikut ini, jika kolom rating adalah null, DECODE menghasilkan nilai 1000:

Function NVL menghasilkan nilai dari argumen keduanya jika argumen pertamanya adalah null. Dalam contoh berikut, jika hire_date adalah null, NVL menghasilkan nilai dari SYSDATE. Sebaliknya, NVL menghasilkan nilai hire_date:

start_date := NVL(hire_date, SYSDATE);

Function REPLACE menghasilkan nilai dari argumen pertamanya jika argumen keduanya null, meskipun argumen opsional ketiganya ada atau tidak. Sebagai contoh, setelah pemberian nilai

new_string := REPLACE(old_string, NULL, my_string);

nilai old_string dan new_string adalah sama.

Jika argumen ketiga adalah null, REPLACE menghasilkan argumen pertamanya dengan setiap hal yang terjadi pada setiap argumen keduanya dihapus. Sebagai contoh, setiap pemberian nilai

syllabified_name := 'Gold-i-locks';
name := REPLACE(syllabified_name, '-', NULL);

nilai dari name adalah ‘goldilocks’

Jika argumen kedua dan ketiganya adalah null, REPLACE secara sederhana menghasilkan argumen pertamanya.

2.8. Built-In Functions

PL/SQL menyediakan banyak function-function yang powerful untuk membantu kita memanipulasi data. Function-function built-in (bawaan) ini terbagi menjadi kategori-kategori berikut:

Tabel 2-3 menunjukkan function-function di dalam setiap kategori.

Kecuali untuk function-function error-reporting SQLCODE dan SQLERRM, kita dapat melihat seluruh function dalam perintah-perintah SQL. Juga, kecuali function-function object-reference DEREF, REF, dan VALUE dan function-function miscellaneous DECODE, DUMP, dan VSIZE, kita dapat menggunakan seluruh function-function dalam perintah-perintah prosedural.

Meskipun fungsi agregat SQL (seperti AVG dan COUNT) dan function-function analitik (seperti CORR dan LAG) tidak disediakan untuk PL/SQL, kita dapat menggunakan mereka dalam perintah-perintah SQL (namun tidak dalam perintah-perintah procedural).

Tabel 2-3 Built-in Functions

Silahkan melanjutkan membaca pembahasan Tipe-tipe Data PL/SQL

 

 

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 Dasar-dasar 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