28 Temmuz 2007 Cumartesi

Varrayler (Değişken Boyutlu Diziler)

VARRAY tipindeki öğelere varray denir. Tek bir belirleyicinin (identifier) bütün bir toplulukla (collection) ilişkilendirilmesine olanak verir. Bir öğeye ulaşmak için standard indisleme yazım kuralı (syntax) kullanılır. Örneğin Grades(3) , Grades adlı varrayin üçüncü öğesini gösterir.

Bir varrayin tip tanımlamasında belirtilmesi zorunlu olan bir maksimum büyüklüğü vardır. İndisinin sabit olan alt sınırı 1'dir, üst sınırı ise genişletilebilir. Bir varrayin hiç öğesi olamayabileceği gibi, tip tanımlamasında belirtilmiş olan maksimum sayıda öğesi de olabilir.

İçiçe Tablolar (Nested Tables)

İçiçe tablolar, veritabanı içinde, tek kolonlu veritabanı tabloları olarak düşünülebilir. Oracle içiçe tablonun satırlarını düzensiz olarak depolar ancak bu tablo bir PL/SQL değişkenine atandığında satırlara 1'den başlayarak ardışık indis değerleri verilir; bu ayrı ayrı satırlara dizi benzeri erişim sağlar. Her bir öğesi bir içiçe tablo olan içiçe tablolar oluşturularak çok boyutlu diziler modellenebilir.

İçiçe tabloları dizilerden ayıran iki önemli özellik vardır:
1) Dizilerin belirlenmiş bir üst sınırı vardır ancak içiçe tablolar sınırlandırılmamıştır ve boyutları dinamik olarak artabilir.

2) Diziler sıkışık olmak zorundadır, yani indisleri ardışık olmalıdır; bu yüzden tek (yalnız) öğeler silinemez. İçiçe tablolar da başta sıkışıktır, ama seyrek hale gelebilirler, yani indisleri ardışık olmayabilir. Bir içiçe tablodan yerleşik yordam (built-in procedure) olan DELETE kullanılarak öğeler silinebilir, bu indiste boşluklar oluşturubilir ama yerleşik (built-in) fonksiyon NEXT, peşpeşe gelen indislerin tekrarlanmasına olanak sağlar.

Topluluk (Collection)

Bir topluluk (collection), hepsi aynı tipten olan düzenli bir grup öğeden oluşur. Her bir öğenin topluluktaki yerini belirleyen yegane (unique) bir indisi (subscript) vardır. PL/SQL şu topluluk tiplerini sunar:

İndisli tablolar (index-by tables) veya birleşmeli dizilerde (associative arrays) gelişigüzel sayılar veya stringler kullanılarak öğelere ulaşılabilir. (Diğer programlama dillerindeki hash tablolarına benzer).

İçiçe tablolar (nested tables) gelişigüzel sayıda öğeyi tutar. İndis olarak sıralı sayıları kullanırlar. İçiçe tablolar veritabanı tablolarında tutularak ve SQL ile idare edilerek eşdeğer SQL tipleri tanımlanabilir.

Varrayler (Değişken boyutlu diziler, Variable-size arrays), sabit sayıda öğe tutarlar ancak bu sayı çalışma zamanında değiştirilebilir. İndis olarak sıralı sayıları kullanırlar. Varraylerin veritabanı tablolarında tutulması sağlanarak eşdeğer SQL tipleri tanımlanabilir. SQL kullanılarak depolanmaları ve erişimleri yapılabilir ancak bu içiçe tablolardaki kadar esnek olmayacaktır.

Öğeleri topluluk olan topluluklar yaratılarak çok boyutlu diziler modellenebilir. Bir uygulamada toplulukları kullanmak için önce PL/SQL tipleri sonra da bu tipte değişkenler tanımlanır. Topluluk tipleri bir yordam (procedure), fonksiyon veya paket (package) içinde tanımlanabilir. Topluluk değişkenleri parametre olarak geçirilebilir.

Tek değerden daha karışık olan verileri aramak için PL/SQL kayıtları (records) veya SQL nesne tipleri topluluklarda tutulabilir. İçiçe tablolar ve varrayler aynı zamanda nesne tiplerinin (object types) nitelikleri (attributes) olabilirler.

NULL İfadesi (NULL Statement)

NULL ifadesi (statement) kontrolü bir sonraki ifadeye geçirmekten başka bir iş yapmaz. Koşulsal bir yapıda (conditional construct), okuyucuya bir olasılığın düşünüldüğünü ancak bir işleme gerek olmadığını gösterir. Aşağıdaki örnekte, isimsiz istisnalar (exceptions) için bir işleme gerek olmadığını gösteriyor:

EXCEPTION
WHEN ZERO_DIVIDE THEN
ROLLBACK;
WHEN VALUE_ERROR THEN
INSERT INTO errors VALUES ...
COMMIT;
WHEN OTHERS THEN
NULL;
END;

NULL ifadesi, IF ifadelerinde ve en az bir yürütülebilir
ifade (executable statement) gerektiren diğer ifadelerde,
yazım kuralına (syntax) uygunluk için kullanılır.
Aşağıdaki örnekte sadece 90'ın üstündeki çalışanlar
ikramiye alıyor:

IF rating > 90 THEN
compute_bonus(emp_id);
ELSE
NULL;
END IF;

NULL ifadesi, test ve debug işlemleri tamamlanmamış
fonksiyon ve yordamların (procedures) geçici olarak
yerlerini tutar (onlar tamamlanana kadar). Aşağıdaki
örnekte NULL ifadesi altprogramda ihtiyaç duyulan
yürütülebilir kısmı (executable part) doldurmaktadır:

PROCEDURE debit_account (acct_id INTEGER, amount REAL) IS
BEGIN
NULL;
END debit_account;

25 Temmuz 2007 Çarşamba

FOR Döngüsü (FOR Loop)

While döngüsünün aksine For döngüsünde tekrar sayısı önceden bellidir, bu tekrarların sınırı tamsayılarla belirlenir. Yazım kuralı (syntax) şöyledir:

FOR Sayac IN [REVERSE] alt_sınır..üst_sınır LOOP
ifadeler
END LOOP;

Sınır değerleri içindeki her bir tamsayı için ifadeler yürütülür ve sayaç bir artırılır. Örneğin:

FOR i IN 1..3 LOOP ---> 1,2,3 değerleri sırayla i'ye atanır
ifadeler ---> 3 kere yürütülür
END LOOP;

'REVERSE' kullanılmazsa sınırlar içindeki tamsayılar küçükten büyüğe atanır, 'REVERSE' kullanılırsa tersten yani büyükten küçüğe atanır ancak sınır değerleri gene küçükten büyüğe yazılmalıdır.

FOR i IN REVERSE 1..3 ---> 3,2,1 değerleri sırayla i'ye atanır
ifadeler ---> 3 kere yürütülür
END LOOP;

Bir For döngüsünün içinde, döngü sayacı bir sabitmiş gibi kullanılabilir ancak kendisine bir değer atanamaz:

FOR ctr IN 1..10 LOOP
IF NOT finished THEN
INSERT INTO ... VALUES (ctr, ...); ---> doğru kullanım
factor := ctr * 2; ---> doğru kullanım
ELSE
ctr := 10; ---> hatalı kullanım
END IF;
END LOOP;

Alttiplerin Kullanımı (Using Subtypes)

Aşağıdaki örnekte Sayac tipinde bir değişkenin bildirimi yapılmaktadır, tipin adı olan 'Sayac' kullanımı hakkında bilgi vermektedir:

DECLARE
SUBTYPE Sayac IS NATURAL;
rows Sayac;

Kullanıcı tanımlı bir alttip (user-defined subtype) türündeki bir değişkenin bildirimi yapılırken aynı zamanda sınırlandırılabilir de, örnek:

DECLARE
SUBTYPE Accumulator IS NUMBER;
total Accumulator(7,2);

Alttiplerin (subtypes) kullanımı, sınır dışına taşan (out-of-range) değerlerin belirlenmesini sağlayarak güvenilirliği artırabilir. Aşağıda Numeral alttipi -9....9 aralığındaki tamsayıları tutacak şekilde sınırlandırılmaktadır, eğer program bu sınırların dışında bir değeri bu değişkende tutmak isterse PL/SQL, istisna (exception) verir:

DECLARE
SUBTYPE Numeral IS NUMBER(1,0);
x_axis Numeral; -- sayı büyüklüklerinin sınırı -9 .. 9
y_axis Numeral;
BEGIN
x_axis := 10; -- VALUE_ERROR verir (hata verir)
...
END;

22 Temmuz 2007 Pazar

Kullanıcı Tanımlı Alttipler (User-Defined Subtypes)

Her bir PL/SQL temel tipi (base type), ona uygulanabilecek bir takım değerler (values) ve işlemler (operations) belirtir. Alttipler de kendi temel tipleri ile aynı işlemleri belirtirler ancak değerlerin sadece bir kısmını belirtirler.

Böylece bir alttip, yeni bir tip değildir ancak temel tipinin sınırlandırılmış bir halidir. Alttipler güvenilirliği artırır, ANSI/ISO tipleri ile uyumluluk sağlar, sabitlerin ve değişkenlerin kullanım amacını göstererek okunurluğu artırır.

PL/SQL 'de CHARACTER ve INTEGER alttipleri şöyle tanımlıdır:
SUBTYPE CHARACTER IS CHAR;
SUBTYPE INTEGER IS NUMBER(38,0); -- sadece tamsayılara izin verir

CHARACTER alttipi sınırlandırılmamış (unconstrained) bir alttiptir çünkü temel tipi olan CHAR ile aynı değerleri belirtir, INTEGER alttipi ise sınırlandırılmış (constrained) bir alttiptir çünkü temel tipi olan NUMBER'ın değerlerinin (values) sadece bir kısmını belirtir.

Tarih ve Zaman (Date and Time) Alttiplerinde Budama (Truncation)

Bazı tarih ve zaman (date and time) tipleri için ayarlanmamış duyarlılıklar (default precisions), mümkün olan en yüksek duyarlılıklardan daha düşüktür. Örneğin, DAY TO SECOND 'da gün (day) için 2, saniye (second) için 6'dır, oysa en yüksek duyarlılıklar her ikisi için de 9'dur.

Değişkenler atanırken ve yordam (procedure) parametreleri geçirilirken, budamadan (truncation) sakınmak için, en yüksek duyarlılık değerlerini kullanan şu alttipler (subtypes) kullanılabilir:

TIMESTAMP_UNCONSTRAINED
TIMESTAMP_TZ_UNCONSTRAINED
TIMESTAMP_LTZ_UNCONSTRAINED
YMINTERVAL_UNCONSTRAINED
DSINTERVAL_UNCONSTRAINED

Günden Saniyeye Aralık Veritipi (Day To Second Interval Datatype)

Günler, saatler, dakikalar ve saniyelerden oluşan aralıkları tutmak ve üzerlerinde değişiklik yapmak için kullanılır. Yazım kuralı (syntax) şöyledir:
INTERVAL DAY[(gün_duyarlılığı)] TO SECOND[(saniye_duyarlılığı)]

duyarlılıklar için 0 ile 9 arasında bir rakam kullanılmalıdır, duyarlılıkların ayarlanmamış (default) değerleri sırasıyla 2 ve 6'dır. Aşağıda günden saniyeye veritipinde bir değişken bildirimi yapılmaktadır:

DECLARE
lag_time INTERVAL DAY(3) TO SECOND(3);
BEGIN IF lag_time > INTERVAL '6' DAY THEN ...
...
END;

Yıldan Aya Aralık Veritipi (Year To Month Interval Datatype)

Yıllardan ve aylardan oluşan zaman aralıklarını tutar. Yazım kuralı (syntax) şöyledir:
INTERVAL YEAR[(duyarlılık)] TO MONTH
duyarlılık, yıl alanındaki basamak sayısını gösterir; 0 ile 4 arasında bir rakam olmalıdır.
Aşağıda aralık veritipine 101 yıl ve 3 ay atanmaktadır:

DECLARE
lifetime INTERVAL YEAR(3) TO MONTH;
BEGIN lifetime := INTERVAL '101-3' YEAR TO MONTH; -- aralık literali
lifetime := '101-3'; -- karakter tipinden dolaylı çevirim
lifetime := INTERVAL '101' YEAR; -- sadece yıllar belirtilebilir
lifetime := INTERVAL '3' MONTH; -- sadece aylar belirtilebilir
...END;