Veri Tabanı Yönetim Sistemleri 2
Ders 6
Ek Bilgiler: Merge, Type, Array, Cursor ve
Dinamik SQL
Yrd. Doç. Dr. Altan MESUT
Trakya Üniversitesi
Bilgisayar Mühendisliği Bölümü
MERGE
• Kaynak ve hedef tablolarda eşleşen değerler varsa
hedef tablodaki değerleri güncelleyen, yoksa
hedef tabloya yeni değer olarak ekleyen DML
komutudur.
MERGE INTO art a USING items i
ON (a.id = i.item_id)
WHEN MATCHED THEN
UPDATE SET a.artist = i.artist,
a.description = i.description
WHEN NOT MATCHED THEN
INSERT VALUES(i.item_id, i.title, i.artist,
i.description);
Database Programming with PL/SQL, Section 3, Lesson 1, Review of SQL DML
TYPE
• Nesne Yönelik Programlama dillerinde kullanılan nesnelere benzer
PL/SQL yapısı CREATE TYPE … AS OBJECT ile oluşturulur:
CREATE TYPE address_typ AS OBJECT (
street
VARCHAR2(30),
city
VARCHAR2(20),
postal_code
VARCHAR2(6)
);
• Bir nesne tanımı içinde başka bir nesne kullanılabilir:
CREATE TYPE employee_typ AS OBJECT (
employee_id
NUMBER(6),
first_name
VARCHAR2(20),
last_name
VARCHAR2(25),
..
address
address_typ
);
CREATE TABLE employees OF employee_typ; şeklinde tablo oluşturulabilir.
Diziler VARRAY türünde TYPE ile oluşturulur
CREATE TYPE Phone_List_Type AS VARRAY(5) OF VARCHAR2(25)
DECLARE
type namesarray IS VARRAY(5) OF VARCHAR2(10);
type grades IS VARRAY(5) OF INTEGER;
names namesarray;
marks grades;
total integer;
BEGIN
names := namesarray('Ali', 'Pınar', 'Ayhan', 'Veli');
marks := grades(98, 97, 78, 87);
total := names.count;
dbms_output.put_line('Total '|| total || ' Students');
FOR i in 1 .. total LOOP
dbms_output.put_line('Student: ' || names(i) || '
Marks: ' || marks(i));
END LOOP;
END;
NOT: VideoRental.sql scriptinde TYPE içinde FUNCTION kullanımını da inceleyiniz.
Cursor'lar: Implicit & Explicit
• Önceki derslerde bahsedilen Cursor hakkında biraz daha
ayrıntılı bilgi vermek gerekirse, cursor aslında sorgu
sonucunun saklandığı alana bir isim verilmesi veya bu alanı
gösteren bir pointer gibi düşünülebilir.
• Database Programming with PL/SQL, Section 5, Lesson 1'e
göre iki tip Cursor'un tanımı şu şekildedir:
– Implicit Cursor: Tüm DML işlemleri için ve tek satır döndüren
sorgular için ORACLE tarafından otomatik olarak tanımlanır.
– Explicit Cursor: Programcı tarafından çok satır döndüren
sorguların saklanması için tanımlanır.
• Bazı kaynaklara göre çok satır döndüren bir sorgu eğer FOR
döngüsü tanımında cursor olarak tanımlanmadan (isim
verilmeden) kullanıldıysa, bu da bir Implicit Cursor
kullanımıdır.
Implicit Cursor FOR döngüsü:
BEGIN
Önceki dersimizde FOR döngüsünü
FOR kayit IN (
adım sayısı bilinen bir işlem için
SELECT *
FOR num IN 1..500 LOOP şeklinde
kullanmıştık. Buradaki kullanım For
FROM Personel
WHERE "BÖLÜM" = 10 Each döngüsüne benzer şekilde
kayıt sayısını bilmemize gerek
ORDER BY Soyad)
kalmadan tüm kayıtlar için çalışır.
LOOP
DBMS_OUTPUT.put_line (
kayit.Ad || ' ' || Kayit.Soyad);
END LOOP;
END;
Explicit Cursor FOR döngüsü:
DECLARE
CURSOR c1 IS
SELECT *
FROM Personel
WHERE "BÖLÜM" = 10
ORDER BY Soyad;
BEGIN
FOR kayit IN c1 LOOP
DBMS_OUTPUT.put_line (
kayit.Ad || ' ' || Kayit.Soyad);
END LOOP;
END;
FETCH kullanımı
DECLARE
CURSOR c1 IS
SELECT Ad, Soyad FROM Personel
WHERE "BÖLÜM" = 10 ORDER BY Soyad;
Ad Personel.Ad%TYPE;
Cursor'lar ile çalışırken FOR
Soyad Personel.Soyad%TYPE;
döngüsü kullanmak yerine
BEGIN
FETCH ile kayıtlar tek tek
OPEN c1;
çekilebilir. Fakat bunun için
LOOP
önce Cursor'u Open ile açmak
FETCH c1 INTO Ad, Soyad;
gerekir. Cursor sorgusunda elde
EXIT WHEN c1%NOTFOUND;
edilen tüm alanlar için
DBMS_OUTPUT.put_line (
değişkenler tanımlamak ta
Ad || ' ' || Soyad);
gerekir. Sona geldiğimizi anlayıp
END LOOP;
döngüden çıkmak için
END;
%NOTFOUND özelliğini
kullanabiliriz.
Cursor Özellikleri (Attributes)
Attribute
Description
%FOUND
Eğer bir INSERT, UPDATE veya DELETE ifadesi bir yada daha çok
satırı etkilediyse veya bir SELECT INTO ifadesi bir yada daha çok
satır döndürdüyse TRUE döndürür.
%NOTFOUND
%FOUND'un mantıksal tersidir. DML işleminde herhangi bir satır
etkilenmediyse veya sorguda döndürülmediyse TRUE döndürür.
%ISOPEN
Cursor açık ise TRUE döndürür. Implicit Cursor'larda hep FALSE
döndürür (çünkü Oracle ilgili SQL ifadesini yürüttükten sonra
otomatik olarak Cursor'u kapatır).
%ROWCOUNT
INSERT, UPDATE veya DELETE ifadelerinden etkilenen, veya SELECT
INTO ifadesinden dönen satır sayısını döndürür.
Execute Immediate ile Dinamik
Sorgular
• Sorgunun yazıldığı ve derlendiği anda
sorgunun parse edilmesi için gerekli bilgilerin
tamamı yoksa, bu bilgilerin bir kısmı çalışma
anında (runtime) elde ediliyorsa bu tip
sorgulara dinamik sorgular denir.
• ORACLE'da EXECUTE IMMEDIATE ifadesi ile
sorgunun dinamik olarak çalıştırılması
mümkündür.
EXECUTE IMMEDIATE Örneği
CREATE OR REPLACE FUNCTION single_number_value (
table_in IN VARCHAR2,
column_in IN VARCHAR2,
where_in IN VARCHAR2)
RETURN NUMBER IS
l_return NUMBER;
BEGIN
EXECUTE IMMEDIATE
BEGIN
'SELECT ' || column_in ||
DBMS_OUTPUT.put_line (
' FROM ' || table_in ||
single_number_value (
' WHERE ' || where_in
'employees',
INTO l_return;
'salary',
RETURN l_return;
'employee_id=138'));
END;
END;
Download

Ders 6 - PL-SQL Ek Bilgiler - Altan MESUT