Kullanılan Tablolar
Bu anlatımda kullanılan örnek veri yapısı
Tüm örnekler klasik Oracle örnek veritabanı olan EMP, DEPT ve SALGRADE tablolarını kullanmaktadır.
EMP Tablosu — Çalışan Bilgileri
| Sütun | Tür | Açıklama |
|---|---|---|
EMPNO |
NUMBER(4) | Çalışan numarası (Primary Key) |
ENAME |
VARCHAR2(10) | Çalışan adı |
JOB |
VARCHAR2(9) | Meslek (PRESIDENT, MANAGER, ANALYST, SALESMAN, CLERK) |
MGR |
NUMBER(4) | Yöneticinin EMPNO'su |
HIREDATE |
DATE | İşe başlama tarihi |
SAL |
NUMBER(7,2) | Maaş |
COMM |
NUMBER(7,2) | Komisyon (bazıları NULL) |
DEPTNO |
NUMBER(2) | Bölüm numarası (Foreign Key) |
📊 EMP Tablo Verilerini Göster
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
|---|---|---|---|---|---|---|---|
| 7839 | KING | PRESIDENT | — | 17-NOV-81 | 5000 | — | 10 |
| 7698 | BLAKE | MANAGER | 7839 | 01-MAY-81 | 2850 | — | 30 |
| 7782 | CLARK | MANAGER | 7839 | 09-JUN-81 | 2450 | — | 10 |
| 7566 | JONES | MANAGER | 7839 | 02-APR-81 | 2975 | — | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 28-SEP-81 | 1250 | 1400 | 30 |
| 7499 | ALLEN | SALESMAN | 7698 | 20-FEB-81 | 1600 | 300 | 30 |
| 7844 | TURNER | SALESMAN | 7698 | 08-SEP-81 | 1500 | 0 | 30 |
| 7900 | JAMES | CLERK | 7698 | 03-DEC-81 | 950 | — | 30 |
| 7521 | WARD | SALESMAN | 7698 | 22-FEB-81 | 1250 | 500 | 30 |
| 7902 | FORD | ANALYST | 7566 | 03-DEC-81 | 3000 | — | 20 |
| 7369 | SMITH | CLERK | 7902 | 17-DEC-80 | 800 | — | 20 |
| 7788 | SCOTT | ANALYST | 7566 | 09-DEC-82 | 3000 | — | 20 |
| 7876 | ADAMS | CLERK | 7788 | 12-JAN-83 | 1100 | — | 20 |
| 7934 | MILLER | CLERK | 7782 | 23-JAN-82 | 1300 | — | 10 |
DEPT Tablosu — Bölüm Bilgileri
| Sütun | Açıklama |
|---|---|
DEPTNO |
Bölüm numarası (10, 20, 30, 40) |
DNAME |
Bölüm adı (ACCOUNTING, RESEARCH, SALES, OPERATIONS) |
LOC |
Şehir (NEW YORK, DALLAS, CHICAGO, BOSTON) |
📊 DEPT Tablo Verilerini Göster
| DEPTNO | DNAME | LOC |
|---|---|---|
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
SALGRADE Tablosu — Maaş Dereceleri
| GRADE | LOSAL (Alt Sınır) | HISAL (Üst Sınır) |
|---|---|---|
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
📊 SALGRADE Tablo Verilerini Göster
| GRADE | LOSAL | HISAL |
|---|---|---|
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
Temel SQL SELECT Deyimleri
Writing Basic SQL Statements
SELECT Deyiminin Kapasiteleri
SQL SELECT deyimi üç temel işlem gerçekleştirir:
- Selection (Seçim): Bir tablodan sadece istenen satırları getirir. WHERE koşulu ile filtreleme yapılır.
- Projection (Projeksiyon): Tablodaki tüm sütunlar yerine yalnızca belirli sütunları seçer.
- Join (Birleştirme): İki veya daha fazla tablodan verileri birleştirir.
Temel SELECT Sözdizimi
SELECT [DISTINCT] {*, column [alias], ...} FROM table;
- SELECT: Hangi sütunları getireceğini belirtir.
- FROM: Hangi tablodan getireceğini belirtir.
- * (asterisk): Tüm sütunları seçmek için kullanılır.
Tüm Sütunları Seçmek — SELECT *
Bir tablodaki tüm sütun ve satırları görmek için * kullanılır.
SELECT * FROM dept;
Belirli Sütunları Seçmek
Sadece istediğimiz sütunları virgülle ayırarak belirtiriz.
SELECT deptno, loc FROM dept;
Aritmetik Operatörler
SQL'de sayısal sütunlar üzerinde aritmetik işlemler yapılabilir: +, -,
*, /
-- Maaşa 300 ekle SELECT ename, sal, sal+300 FROM emp;
Operatör Önceliği
Matematikteki öncelik kuralları geçerlidir: Çarpma ve bölme, toplama ve çıkarmadan önce yapılır.
SELECT 12*sal+100 FROM emp; -- KING: 12*5000+100 = 60100
SELECT 12*(sal+100) FROM emp; -- KING: 12*(5000+100) = 61200
NULL Değerleri
NULL, kullanılamaz, atanmamış, bilinmeyen veya uygulanamaz bir değeri temsil eder. Boş string veya 0 ile aynı değildir.
NULL değer içeren herhangi bir aritmetik ifadenin sonucu her zaman NULL'dur. Örneğin:
12 * SAL + COMM — COMM sütunu NULL ise sonuç da NULL olur.
SELECT ename, 12*sal+comm FROM emp WHERE ename='KING'; -- KING'in COMM değeri NULL olduğundan sonuç NULL döner
Sütun Takma Adları (Column Aliases)
Sorgu sonucunda sütunlara daha okunabilir isimler vermek için alias kullanılır.
-- AS anahtar kelimesiyle veya doğrudan boşlukla SELECT ename AS name, sal salary FROM emp; -- Boşluk içeren alias için çift tırnak kullanılır SELECT ename "Name", sal*12 "Annual Salary" FROM emp;
Alias büyük/küçük harf duyarsızdır. Ancak boşluk, özel karakter veya büyük/küçük harf hassasiyeti istenirse çift tırnak ("...") kullanılmalıdır. Tek tırnak ('...') string değerler içindir, alias için değil.
Tekrarlayan Satırları Kaldırmak — DISTINCT
Varsayılan olarak tüm satırlar (tekrarlar dahil) gösterilir. DISTINCT anahtar kelimesi
tekrarlayan satırları kaldırır.
SELECT deptno FROM emp; -- 10, 30, 10, 20 ... 14 satır
SELECT DISTINCT deptno FROM emp; -- 10, 20, 30 — sadece 3 satır
Tüm çalışanların adını ve maaşını görüntüleyin.
SELECT ENAME, SAL FROM EMP;
EMP tablosundan tekrarlayan meslekler olmaksızın tüm meslekleri listeleyin.
SELECT DISTINCT JOB FROM EMP;
Veriyi Kısıtlama ve Sıralama
Restricting and Sorting Data
WHERE Cümlesi ile Satır Filtreleme
WHERE cümlesi, döndürülen satırları koşula göre sınırlandırır. FROM cümlesinden sonra gelir.
SELECT [DISTINCT] {* | column [alias], ...} FROM table [WHERE condition(s)];
SELECT ename, job, deptno FROM emp WHERE job='CLERK';
Karakter stringleri ve tarih değerleri tek tırnak içine alınır ('CLERK'). Karakter
değerleri büyük/küçük harf duyarlıdır. Tarih değerleri format duyarlıdır. Varsayılan tarih formatı
DD-MON-YY'dir. (Örnek: 17-NOV-81)
Karşılaştırma Operatörleri
| Operatör | Anlamı | Örnek |
|---|---|---|
= |
Eşittir | job = 'CLERK' |
> |
Büyüktür | sal > 2000 |
>= |
Büyük eşittir | sal >= 1000 |
< |
Küçüktür | sal < 3000 |
<= |
Küçük eşittir | sal <= comm |
<> veya != |
Eşit değildir | deptno <> 20 |
Diğer Karşılaştırma Operatörleri
BETWEEN ... AND ... — Aralık Operatörü
İki değer arasındaki satırları getirir. Alt ve üst sınırlar dahildir (inclusive).
SELECT ename, sal FROM emp WHERE sal BETWEEN 1000 AND 1500; -- 1000 ve 1500 dahil tüm maaşları getirir -- MARTIN(1250), TURNER(1500), WARD(1250), ADAMS(1100), MILLER(1300)
IN(list) — Liste Operatörü
Belirtilen listedeki herhangi bir değerle eşleşen satırları getirir.
SELECT empno, ename, sal, mgr FROM emp WHERE mgr IN (7902, 7566, 7788); -- Yöneticisi 7902, 7566 veya 7788 olan çalışanlar
LIKE — Desen Eşleştirme Operatörü
Wildcard karakterlerle metin deseni arama yapar:
- % (yüzde): Sıfır veya daha fazla karakteri temsil eder.
- _ (alt çizgi): Tam olarak bir karakteri temsil eder.
-- 'S' harfiyle başlayan isimler SELECT ename FROM emp WHERE ename LIKE 'S%'; -- SMITH, SCOTT -- İkinci harfi 'A' olan isimler (herhangi biriyle başlar) SELECT ename FROM emp WHERE ename LIKE '_A%'; -- MARTIN, JAMES, WARD
IS NULL — Null Kontrol Operatörü
NULL değer kontrolü için = kullanılamaz; IS NULL veya IS NOT NULL
kullanılır.
-- Yöneticisi olmayan çalışanlar (KING) SELECT ename, mgr FROM emp WHERE mgr IS NULL;
Mantıksal Operatörler (AND, OR, NOT)
| Operatör | Açıklama |
|---|---|
AND |
Her iki koşul da TRUE olmalıdır |
OR |
Koşullardan en az biri TRUE olmalıdır |
NOT |
Koşulun olumsuzunu alır (FALSE ise TRUE döner) |
-- Hem maaşı 1100+ hem mesleği CLERK olanlar SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 AND job='CLERK'; -- ADAMS(1100), MILLER(1300)
-- Mesleği CLERK, MANAGER veya ANALYST OLMAYAN çalışanlar SELECT ename, job FROM emp WHERE job NOT IN ('CLERK', 'MANAGER', 'ANALYST'); -- NOT BETWEEN, NOT LIKE, NOT NULL ile de kullanılabilir
ORDER BY Cümlesi ile Sıralama
Sonuçların sırası belirsizdir. ORDER BY ile sıralama yapılır.
- ASC: Artan sıralama (varsayılan, yazılmak zorunda değil)
- DESC: Azalan sıralama
-- İşe alım tarihine göre artan sıralama SELECT ename, job, deptno, hiredate FROM emp ORDER BY hiredate; -- Azalan tarih sıralaması SELECT ename, hiredate FROM emp ORDER BY hiredate DESC; -- Alias ile sıralama SELECT empno, ename, sal*12 annsal FROM emp ORDER BY annsal; -- Çoklu sütunla sıralama (önce deptno, sonra sal azalan) SELECT ename, deptno, sal FROM emp ORDER BY deptno, sal DESC;
ORDER BY ile SELECT listesinde olmayan sütunlara göre de sıralama yapılabilir. Çoklu sıralamada önce yazılan sütun birincil, sonraki sütunlar ikincil sıralama kriteridir.
Maaşı 1000'den fazla olan ve departman numarası 10 veya 20'de çalışan çalışanların adını ve maaşını 'Name' ve 'Monthly Salary' sütun adlarıyla listeleyin.
SELECT ENAME "NAME", SAL "MONTHLY SALARY" FROM EMP WHERE SAL > 1000 AND DEPTNO IN(10, 20);
Meslekleri PRESIDENT veya MANAGER olan çalışanların adlarını ve departman numaralarını isme göre alfabetik sıralayarak listeleyin.
SELECT ename, deptno FROM emp WHERE job IN ('PRESIDENT', 'MANAGER') ORDER BY ename;
Maaşı 1000, 3000 veya 5000 olmayan tüm çalışanların adını, mesleğini ve maaşını görüntüleyin.
SELECT ename, job, sal FROM emp WHERE sal NOT IN (1000, 3000, 5000);
Tek Satır Fonksiyonları
Single-Row Functions
Tek satır fonksiyonlar her satır için bir sonuç döndürür. SELECT, WHERE ve ORDER BY cümlelerinde kullanılabilirler.
Büyük/Küçük Harf Dönüşüm Fonksiyonları
| Fonksiyon | Açıklama | Örnek | Sonuç |
|---|---|---|---|
UPPER(str) |
Tümü büyük harfe çevirir | UPPER('hello') |
HELLO |
LOWER(str) |
Tümü küçük harfe çevirir | LOWER('HELLO') |
hello |
INITCAP(str) |
İlk harfi büyük yapar | INITCAP('hello world') |
Hello World |
-- WHERE koşulunda büyük/küçük harf sorununu çöz SELECT empno, ename, deptno FROM emp WHERE ename = UPPER('blake'); -- Kullanıcı 'blake' yazsa da UPPER sayesinde 'BLAKE' olarak aranır
Karakter Manipülasyon Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
CONCAT(s1, s2) |
İki stringi birleştirir (|| ile de yapılabilir) |
CONCAT('MARTIN','SALESMAN') → MARTINSALESMAN |
SUBSTR(str, pos, len) |
Alt string alır (pos'tan başlayıp len karakter) | SUBSTR('SALESMAN',1,5) → SALES |
LENGTH(str) |
Karakterin uzunluğunu döndürür | LENGTH('MARTIN') → 6 |
INSTR(str, substr) |
Alt stringin ilk konumunu döndürür | INSTR('MARTIN','A') → 2 |
SELECT ename, CONCAT(ename, job), LENGTH(ename), INSTR(ename, 'A') FROM emp WHERE SUBSTR(job, 1, 5) = 'SALES'; -- Mesleği SALES ile başlayan çalışanlar için çeşitli karakter işlemleri
Tarih Aritmetiği
Oracle'da tarihler üzerinde aritmetik işlemler yapılabilir. İki tarih arasındaki fark gün cinsindendir.
-- Çalışanın kaç haftadır çalıştığını hesapla SELECT ename, (SYSDATE - hiredate) / 7 WEEKS FROM emp WHERE deptno = 10; -- SYSDATE: Geçerli sistem tarih ve saatini döndürür -- Gün farkını 7'ye bölerek hafta sayısı bulunur
SYSDATE, veritabanı sunucusunun anlık tarih ve saatini döndürür. Parametre almaz. INSERT işlemlerinde de kullanışlıdır: işe başlama tarihi olarak SYSDATE yazılabilir.
Birden Fazla Tablodan Veri Görüntüleme
Displaying Data from Multiple Tables — JOIN'ler
JOIN Nedir?
JOIN, birden fazla tabloyu ortak sütunlar aracılığıyla birleştirip tek bir sonuç kümesi oluşturmaktır. JOIN koşulu WHERE cümlesine yazılır.
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;
Aynı sütun adı birden fazla tabloda varsa, hangi tabloya ait olduğunu belirtmek için
tablo_adi.sutun_adi formatı kullanılır. Aksi halde SQL hatası oluşur.
Equijoin (Eşit Join)
İki tablo arasında eşitlik koşuluyla yapılan birleştirmedir. En yaygın JOIN türüdür. EMP tablosundaki DEPTNO (foreign key) ile DEPT tablosundaki DEPTNO (primary key) eşlenerek birleştirilir.
SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.loc FROM emp, dept WHERE emp.deptno = dept.deptno;
Tablo Alias'ı Kullanmak
Sorguları kısaltmak ve okunabilirliği artırmak için tablolara takma ad verilir.
SELECT e.empno, e.ename, e.deptno, d.deptno, d.loc FROM emp e, dept d WHERE e.deptno = d.deptno; -- 'e' emp tablosunu, 'd' dept tablosunu temsil eder
Non-Equijoin (Eşitsizlik Joini)
Eşitlik dışındaki koşullarla yapılan birleştirmedir. EMP tablosundaki SAL ile SALGRADE tablosundaki LOSAL-HISAL arasındaki ilişki buna örnektir — EMP'de SALGRADE'e doğrudan eşleşen bir sütun yoktur.
-- Her çalışanın maaş derecesini bul SELECT e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal; -- SAL, LOSAL ile HISAL arasında olduğunda eşleşme sağlanır
Outer Join (Dış Birleştirme)
Normal JOIN'de eşleşmeyen satırlar sonuçta görünmez. Outer Join, eşleşmese bile bir
tablodaki TÜM satırları göstermek için kullanılır. Oracle sözdiziminde (+) operatörü "eksik
tarafı tamamla" anlamına gelir.
-- Çalışanı olmayan bölümler de dahil tüm bölümleri göster SELECT e.ename, d.deptno, d.dname FROM emp e, dept d WHERE e.deptno(+) = d.deptno ORDER BY e.deptno; -- (+) eksik taraftaki tabloya eklenir (burada EMP tarafı) -- OPERATIONS departmanı çalışan olmasa da görünür
(+) operatörü, satırı eksik olan (az veri içeren) tablonun tarafına konur. Bu sayede
diğer tablo tam olarak listelenir. Modern SQL'de bunun karşılığı LEFT JOIN,
RIGHT JOIN veya FULL OUTER JOIN'dir.
Self Join (Öz Birleştirme)
Bir tablonun kendisiyle birleştirilmesidir. Hiyerarşik ilişkileri sorgulamak için kullanılır. EMP tablosunda her çalışanın MGR sütunu, aynı tablodaki başka bir çalışanın EMPNO'suna referans verir.
-- "X, Y için çalışıyor" çıktısı SELECT worker.ename || ' works for ' || manager.ename FROM emp worker, emp manager WHERE worker.mgr = manager.empno; -- EMP tablosu hem 'worker' hem 'manager' alias'ıyla kullanılıyor -- Çıktı: BLAKE works for KING, CLARK works for KING, vs.
İsminde 'K' geçen tüm çalışanların adını ve çalıştıkları departmanın adını görüntüleyin.
SELECT e.ename, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename LIKE '%K%';
Tüm çalışanlar için çalışan adı, meslek, departman adı, maaş ve maaş derecesini görüntüleyin.
SELECT e.ename, e.job, d.dname, e.sal, s.grade FROM emp e, dept d, salgrade s WHERE e.deptno = d.deptno AND e.sal BETWEEN s.losal AND s.hisal;
Gruplama Fonksiyonları ile Veri Toplama
Aggregating Data Using Group Functions
Gruplama Fonksiyonları Nedir?
Gruplama (aggregate) fonksiyonları, satır kümeleri üzerinde işlem yaparak her grup için tek bir sonuç döndürür. COUNT(*) dışındaki tüm gruplama fonksiyonları NULL değerleri yok sayar.
| Fonksiyon | Açıklama |
|---|---|
AVG(col) |
Ortalama değeri hesaplar |
COUNT(*) |
Tüm satır sayısını döndürür (NULL dahil) |
COUNT(col) |
NULL olmayan satır sayısını döndürür |
MAX(col) |
Maksimum değeri döndürür |
MIN(col) |
Minimum değeri döndürür |
SUM(col) |
Toplam değeri hesaplar |
STDDEV(col) |
Standart sapmayı hesaplar |
VARIANCE(col) |
Varyansı hesaplar |
-- Satıcıların maaş istatistikleri SELECT AVG(sal), MAX(sal), MIN(sal), SUM(sal) FROM emp WHERE job LIKE 'SALES%';
COUNT Fonksiyonu
-- Departman 30'daki çalışan sayısı (NULL dahil tüm satırlar) SELECT COUNT(*) FROM emp WHERE deptno = 30; -- Sonuç: 6 -- Komisyonu NULL olmayan satır sayısı SELECT COUNT(comm) FROM emp WHERE deptno = 30; -- Sonuç: 4 (sadece NULL olmayanlar sayılır)
NULL Değerler ve NVL Fonksiyonu
Gruplama fonksiyonları NULL değerleri atlar. Eğer NULL değerleri de hesaba katmak istiyorsak
NVL fonksiyonu kullanılır.
-- NULL'ları yok sayarak ortalama (sadece 4 kişi üzerinden) SELECT AVG(comm) FROM emp; -- Sonuç: 550 (2200/4 — NULL olanlar sayılmaz) -- NULL'ları 0 sayarak tüm çalışanlar üzerinden ortalama SELECT AVG(NVL(comm, 0)) FROM emp; -- Sonuç: 157.14 (2200/14 — tüm 14 çalışan sayılır)
GROUP BY Cümlesi ile Gruplama
Tabloyu küçük gruplara bölmek için kullanılır. SELECT listesinde gruplama fonksiyonu dışındaki tüm sütunların GROUP BY'da belirtilmesi gerekir.
-- Her departmandaki ortalama maaş SELECT deptno, AVG(sal) FROM emp GROUP BY deptno; -- Sonuç: 10→2916.67, 20→2175, 30→1566.67 -- Departman ve meslekle çoklu gruplama SELECT deptno, job, SUM(sal) FROM emp GROUP BY deptno, job;
SELECT'te bulunan deptno gibi düz sütunlar GROUP BY'da belirtilmezse ORA-00979 hatası
alınır. Gruplama fonksiyonu (AVG, SUM vs.) olan sütunlar GROUP BY'a girmez.
HAVING Cümlesi ile Grup Filtreleme
WHERE bireysel satırları filtreler. HAVING ise gruplanmış sonuçları filtreler. Gruplama fonksiyonlarını WHERE'de kullanamazsınız; bunun için HAVING kullanılır.
-- Maksimum maaşı 2900'den yüksek olan departmanlar SELECT deptno, MAX(sal) FROM emp GROUP BY deptno HAVING MAX(sal) > 2900; -- Dept 10 (5000) ve Dept 20 (3000) -- WHERE + GROUP BY + HAVING + ORDER BY birlikte SELECT job, SUM(sal) PAYROLL FROM emp WHERE job NOT LIKE 'SALES%' GROUP BY job HAVING SUM(sal) > 5000 ORDER BY SUM(sal);
Gruplama Fonksiyonlarını İç İçe Kullanmak
Gruplama fonksiyonları iç içe kullanılabilir. Bu şekilde "grupların grubu" hesaplanabilir.
-- Departman ortalamalarının en yükseği SELECT MAX(AVG(sal)) FROM emp GROUP BY deptno; -- Önce her dept ortalanır: 2916.67, 2175, 1566.67 -- Sonra bunların maksimumu alınır: 2916.67
Yalnızca EMP tablosunu kullanarak kaç departman numarası olduğunu görüntüleyin.
-- Egzersiz 8: Toplam dept sayısı (tekrarlar dahil) SELECT COUNT(deptno) FROM emp; -- Egzersiz 9: Benzersiz dept sayısı SELECT COUNT(DISTINCT deptno) FROM emp;
Alt Sorgular (Subqueries)
Subqueries
Alt Sorgu Nedir?
Alt sorgu, başka bir sorgunun içine gömülmüş SELECT sorgusudur. İç sorgu (subquery) önce çalışır ve sonucu dış sorgu (main query) tarafından kullanılır. WHERE veya HAVING cümlesinde, hatta FROM cümlesinde kullanılabilir.
SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table);
SELECT ename FROM emp WHERE sal > (SELECT sal FROM emp WHERE empno = 7566); -- İç sorgu Jones'in maaşını (2975) döndürür -- Dış sorgu 2975'ten fazla kazananları getirir: KING, FORD, SCOTT
Alt Sorgu Türleri
🔹 Tek Satır Alt Sorgu
İç sorgu yalnızca bir satır döndürür. =, >,
<, >=, <=, <> operatörleriyle
kullanılır.
🔸 Çok Satırlı Alt Sorgu
İç sorgu birden fazla satır döndürür. IN, ANY,
ALL operatörleriyle kullanılır.
-- Mesleği Smith ile aynı VE maaşı Adams'tan yüksek olan çalışanlar SELECT ename, job FROM emp WHERE job = (SELECT job FROM emp WHERE empno = 7369) AND sal > (SELECT sal FROM emp WHERE empno = 7876); -- Sonuç: MILLER
Gruplama Fonksiyonu ile Alt Sorgu
-- En düşük maaşlı çalışan SELECT ename, job, sal FROM emp WHERE sal = (SELECT MIN(sal) FROM emp); -- Sonuç: SMITH, CLERK, 800
Çok Satırlı Alt Sorgular: IN, ANY, ALL
| Operatör | Anlamı |
|---|---|
IN |
Listedeki herhangi bir değere eşit |
<ANY |
Listedeki maksimumdan küçük |
>ANY |
Listedeki minimumdan büyük |
=ANY |
IN ile eşdeğer |
>ALL |
Listedeki maksimumdan büyük |
<ALL |
Listedeki minimumdan küçük |
-- CLERK olmayan ama herhangi bir CLERK'ten az kazananlar SELECT empno, ename, job FROM emp WHERE sal < ANY (SELECT sal FROM emp WHERE job = 'CLERK') AND job <> 'CLERK'; -- <ANY = maksimumdan az (en yüksek CLERK maaşından az)
-- Her departman ortalamasından yüksek maaş kazananlar SELECT empno, ename, job FROM emp WHERE sal > ALL (SELECT AVG(sal) FROM emp GROUP BY deptno); -- >ALL = tüm değerlerden büyük = maksimumdan büyük -- KING, JONES, FORD, SCOTT
FROM Cümlesinde Alt Sorgu (Inline View)
FROM cümlesinde bir alt sorgu kullanılabilir. Bu yapıya Inline View denir. Sanki geçici bir tablo gibi davranır.
-- Departman ortalamasından fazla kazanan çalışanlar SELECT a.ename, a.sal, a.deptno, b.salavg FROM emp a, (SELECT deptno, AVG(sal) salavg FROM emp GROUP BY deptno) b WHERE a.deptno = b.deptno AND a.sal > b.salavg;
Eğer = operatörüyle kullandığınız alt sorgu birden fazla satır döndürürse
ORA-01427: single-row subquery returns more than one row hatası alırsınız. Bu durumda
IN veya diğer çok satır operatörlerini kullanın.
Mesleği Jones ile aynı olan VE Jones'tan sonra işe başlayan çalışanların adı ve maaşını görüntüleyin.
SELECT ename, sal FROM emp WHERE job = (SELECT job FROM emp WHERE ename LIKE 'JONES') AND hiredate > (SELECT hiredate FROM emp WHERE ename LIKE 'JONES');
Ortalama maaştan fazla kazanan tüm çalışanların numarasını ve adını görüntüleyin.
SELECT empno, ename FROM emp WHERE sal > (SELECT AVG(sal) FROM emp);
Her departmandaki minimum maaşı departman numarasına göre sıralayarak görüntüleyin.
SELECT deptno, MIN(sal) FROM emp GROUP BY deptno ORDER BY deptno;
En fazla çalışana sahip departmanın numarasını bulun.
SELECT DISTINCT e.deptno FROM emp e, (SELECT deptno, COUNT(empno) numberofemp FROM emp GROUP BY deptno) c WHERE c.numberofemp = (SELECT MAX(COUNT(empno)) FROM emp GROUP BY deptno) AND e.deptno = c.deptno;
SELECT e.deptno FROM emp e GROUP BY e.deptno HAVING COUNT(empno) = (SELECT MAX(COUNT(empno)) FROM emp GROUP BY deptno);
Çok Sütunlu Alt Sorgular
Multiple-Column Subqueries
Çok Sütunlu Alt Sorgu Nedir?
Alt sorgunun birden fazla sütun döndürdüğü durumlardır. Ana sorgu bu çok sütunlu değerlerle karşılaştırma yapar. Sütunlar parantez içinde eşleştirilir.
-- 605 numaralı siparişle hem aynı ürünü hem aynı miktarı içeren diğer siparişler SELECT ordid, prodid, qty FROM item WHERE (prodid, qty) IN (SELECT prodid, qty FROM item WHERE ordid = 605) AND ordid <> 605;
NULL Değer ve NOT IN ile Oluşan Sorun
NOT IN operatörü içeren alt sorgu NULL değer döndürürse, sonuç her zaman boş döner. Bunun nedeni NOT
IN'in !=ALL'a eşdeğer olmasıdır ve NULL karşılaştırması her zaman FALSE üretir.
-- Hiç astı olmayan çalışanları bulmaya çalışıyoruz SELECT ename FROM emp employee WHERE empno NOT IN (SELECT mgr FROM emp manager); -- SORUN: MGR sütununda NULL var (KING'in yöneticisi yok) -- Bu yüzden hiç satır dönmez! -- ÇÖZÜM: WHERE mgr IS NOT NULL koşulu eklenmelidir
Veri Manipülasyonu — DML
Manipulating Data — INSERT, UPDATE, DELETE
INSERT — Yeni Satır Ekleme
INSERT INTO deyimi tabloya yeni satır ekler. Bu sözdizimde bir seferde yalnızca tek satır
eklenir.
INSERT INTO table [(column [, column...])] VALUES (value [, value...]);
-- Sütun listesi belirterek (güvenli yöntem) INSERT INTO dept (deptno, dname, loc) VALUES (50, 'DEVELOPMENT', 'DETROIT');
NULL Değer Eklemek
-- Örtük yöntem: LOC sütununu atla (NULL olur) INSERT INTO dept (deptno, dname) VALUES (60, 'MIS'); -- Açık yöntem: NULL anahtar kelimesini yaz INSERT INTO dept VALUES (70, 'FINANCE', NULL);
SYSDATE ile Tarih Eklemek
INSERT INTO emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) VALUES (7196, 'GREEN', 'SALESMAN', 7782, SYSDATE, 2000, NULL, 10);
TO_DATE ile Belirli Tarih Formatı
INSERT INTO emp VALUES (2296, 'AROMANO', 'SALESMAN', 7782, TO_DATE('FEB 3, 1997', 'MON DD, YYYY'), 1300, NULL, 10);
Alt Sorgu ile Çok Satır Eklemek
-- Meslekleri MANAGER olan tüm çalışanları başka tabloya kopyala INSERT INTO managers(id, name, salary, hiredate) SELECT empno, ename, sal, hiredate FROM emp WHERE job = 'MANAGER'; -- VALUES cümlesi kullanılmaz, sütun sayıları eşleşmeli
UPDATE — Mevcut Satırları Güncelleme
Tablodaki mevcut satırları değiştirmek için kullanılır. WHERE olmadan tüm satırlar güncellenir.
-- Belirli satırı güncelle UPDATE emp SET deptno = 20 WHERE empno = 7782; -- Çok sütunlu alt sorgu ile güncelleme UPDATE emp SET (job, deptno) = (SELECT job, deptno FROM emp WHERE empno = 7499) WHERE empno = 7698; -- 7499'un meslek ve departmanını 7698'e kopyalar
WHERE cümlesi belirtilmezse tablodaki tüm satırlar güncellenir. Bu geri
alınabilir ancak çok büyük bir yanlışlık olabilir. Her zaman dikkatli olun.
DELETE — Satır Silme
Tablodan mevcut satırları kaldırır. WHERE olmadan tüm satırlar silinir.
-- Belirli bir satırı sil DELETE FROM department WHERE dname = 'DEVELOPMENT'; -- Alt sorgu ile başka tablodaki değere göre sil DELETE FROM employee WHERE deptno = (SELECT deptno FROM dept WHERE dname = 'SALES'); -- SALES departmanındaki tüm çalışanları siler (6 satır)
COMMIT, ROLLBACK ve SAVEPOINT — İşlem Kontrolü
DML işlemleri (INSERT, UPDATE, DELETE) otomatik olarak veritabanına kaydedilmez; bir transaction (işlem) içinde bekler.
| Komut | Açıklama |
|---|---|
COMMIT |
Tüm bekleyen değişiklikleri kalıcı olarak veritabanına yazar |
ROLLBACK |
Tüm bekleyen değişiklikleri geri alır |
SAVEPOINT name |
Transaction içinde bir geri dönüş noktası oluşturur |
ROLLBACK TO name |
Belirtilen savepoint'e kadar geri alır |
COMMIT Öncesi Durum
- Önceki veri kurtarılabilir durumdadır.
- Mevcut kullanıcı SELECT ile değişiklikleri görebilir.
- Diğer kullanıcılar değişiklikleri göremez.
- Etkilenen satırlar kilitlidir (diğerleri değiştiremez).
COMMIT Sonrası Durum
- Değişiklikler kalıcı olarak veritabanına yazılır.
- Önceki veri geri getirilemez.
- Tüm kullanıcılar sonuçları görebilir.
- Kilitlenen satırlar serbest bırakılır.
- Tüm savepoint'ler silinir.
UPDATE emp SET deptno = 10 WHERE empno = 7782; COMMIT; -- Değişiklik kalıcı hale geldi -- Hata yapıldı, tüm değişiklikleri geri al DELETE FROM employee; ROLLBACK; -- 14 satır geri geldi!
Tablo Oluşturma ve Yönetme
Creating and Managing Tables — DDL
CREATE TABLE — Tablo Oluşturma
Tablo oluşturmak için CREATE TABLE yetkisi ve depolama alanı gereklidir.
CREATE [GLOBAL TEMPORARY] TABLE [schema.]table (column datatype [DEFAULT expr][, ...]);
CREATE TABLE dept (deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13)); -- Tablo yapısını doğrula DESCRIBE dept;
Oracle Veri Tipleri
| Tip | Açıklama |
|---|---|
VARCHAR2(size) |
Değişken uzunluklu karakter verisi. En yaygın kullanılan string tipidir. |
CHAR(size) |
Sabit uzunluklu karakter verisi (eksik kısımlar boşlukla doldurulur) |
NUMBER(p,s) |
Sayısal veri. p: toplam basamak sayısı, s: ondalık basamak sayısı |
DATE |
Tarih ve saat bilgisi (DD-MON-YY formatı) |
LONG |
2 GB'a kadar değişken uzunluklu karakter |
CLOB |
4 GB'a kadar tek baytlı karakter verisi |
BLOB |
4 GB'a kadar ikili (binary) veri |
RAW / LONG RAW |
Ham ikili veri |
BFILE |
Harici dosyada saklanan ikili veri (4 GB'a kadar) |
Alt Sorgu ile Tablo Oluşturma
CREATE TABLE ve SELECT'i birleştirerek hem tablo oluşturulabilir hem de veri eklenebilir.
CREATE TABLE dept30 AS SELECT empno, ename, sal*12 ANNSAL, hiredate FROM emp WHERE deptno = 30; -- dept30 tablosu oluşturulur VE Dept 30 çalışanları eklenir
ALTER TABLE — Tablo Değiştirme
Mevcut tabloya sütun ekleme, sütun değiştirme ve sütun silme için kullanılır.
-- Sütun ekleme (ADD) ALTER TABLE dept30 ADD (job VARCHAR2(9)); -- Yeni sütun tablonun sonuna eklenir, değerleri NULL olur -- Sütun boyutunu değiştirme (MODIFY) ALTER TABLE dept30 MODIFY (ename VARCHAR2(15)); -- Boyut artırılabilir; küçültme için sütun boş olmalı -- Sütun silme (DROP COLUMN) ALTER TABLE dept30 DROP COLUMN job;
DROP TABLE — Tablo Silme
DROP TABLE dept30;
DROP TABLE tablo yapısını ve tüm veriyi siler. Bekleyen tüm işlemler COMMIT edilir. Tüm index'ler kaldırılır. Bu işlem geri alınamaz (ROLLBACK edilemez). Çok dikkatli kullanılmalıdır.
Kısıtlamalar (Constraints)
Including Constraints
Kısıtlamalar, tablo seviyesinde veri bütünlüğünü sağlayan kurallardır. Tablo oluştururken veya sonradan ALTER TABLE ile eklenebilirler.
Kısıtlama Türleri
NOT NULL — Boş Değer Yasağı
O sütuna NULL değer girilmesini engeller. Yalnızca sütun düzeyinde tanımlanır.
CREATE TABLE emp( empno NUMBER(4), ename VARCHAR2(10) NOT NULL, -- zorunlu alan deptno NUMBER(7,2) NOT NULL);
UNIQUE KEY — Benzersizlik Kısıtlaması
Sütundaki tüm değerlerin benzersiz olmasını sağlar. NULL değerlere izin verilir (birden fazla NULL olabilir çünkü NULL = NULL değildir).
CREATE TABLE dept( deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13), CONSTRAINT dept_dname_uk UNIQUE(dname)); -- Aynı departman adı iki kez girilemez
PRIMARY KEY — Birincil Anahtar
Satırı benzersiz olarak tanımlayan anahtardır. NULL olamaz ve benzersiz olmalıdır. Her tabloda yalnızca bir PRIMARY KEY olabilir ancak birden fazla sütunu kapsayabilir (bileşik anahtar).
CREATE TABLE dept( deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13), CONSTRAINT dept_dname_uk UNIQUE (dname), CONSTRAINT dept_deptno_pk PRIMARY KEY(deptno));
FOREIGN KEY — Yabancı Anahtar
Bir tablodaki değerin başka bir tablonun primary key değerleriyle uyumlu olmasını zorunlu kılar. Referans bütünlüğünü sağlar.
CREATE TABLE emp( empno NUMBER(4), ename VARCHAR2(10) NOT NULL, deptno NUMBER(7,2) NOT NULL, CONSTRAINT emp_deptno_fk FOREIGN KEY (deptno) REFERENCES dept (deptno));
FOREIGN KEY tanımına ON DELETE CASCADE eklenirse, parent tablodaki (üst tablo) bir satır
silindiğinde buna bağlı child tablodaki (alt tablo) satırlar da otomatik silinir.
CHECK — Koşul Kısıtlaması
Her satırın karşılaması gereken bir koşul tanımlar. Diğer satırlara referans veremez, SYSDATE, ROWNUM gibi pseudosütunları kullanamaz.
deptno NUMBER(2), CONSTRAINT emp_deptno_ck CHECK (DEPTNO BETWEEN 10 AND 99)
Kısıtlama Yönetimi
-- Kısıtlama ekleme ALTER TABLE emp ADD CONSTRAINT emp_mgr_fk FOREIGN KEY(mgr) REFERENCES emp(empno); -- Kısıtlama kaldırma ALTER TABLE emp DROP CONSTRAINT emp_mgr_fk; -- PRIMARY KEY kaldırma + bağlı FK'ları da kaldır ALTER TABLE dept DROP PRIMARY KEY CASCADE; -- Kısıtlamayı geçici devre dışı bırakma ALTER TABLE emp DISABLE CONSTRAINT emp_empno_pk CASCADE; -- Kısıtlamayı tekrar etkinleştirme ALTER TABLE emp ENABLE CONSTRAINT emp_empno_pk;
Kısıtlamaları Görüntüleme
-- Tablodaki tüm kısıtlamalar SELECT constraint_name, constraint_type, search_condition FROM user_constraints WHERE table_name = 'EMP'; -- Kısıtlamaların hangi sütunlara uygulandığı SELECT constraint_name, column_name FROM user_cons_columns WHERE table_name = 'EMP';
View (Görünüm)
Views
View Nedir?
View, bir SELECT sorgusunun sonucuna dayanan sanal bir tablodur. Gerçek veri içermez; veriyi altındaki tablolardan türetir. "Saklanmış sorgu" olarak da düşünülebilir.
- Bir veya daha fazla tablonun özelleştirilmiş sunumudur.
- Veri bütünlüğü için ek güvenlik katmanı sağlar (belirli sütun/satırları gizler).
- Karmaşık sorguları basitleştirir.
- Veri içermez, her sorguda altındaki tablolardan çeker.
View Oluşturma
CREATE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition;
-- Mesleği CLERK olan çalışanların adı ve maaşını gösteren view CREATE VIEW Clerk AS SELECT ename, sal FROM emp WHERE job = 'CLERK';
CREATE VIEW EmpDepartments AS SELECT emp.ename, dept.deptno, dept.dname FROM emp, dept WHERE emp.deptno = dept.deptno;
View'da Sütun Yeniden Adlandırma
CREATE VIEW Clerk (clerkName, clerkSalary) AS SELECT ename, sal FROM emp WHERE job = 'CLERK'; -- View sütunları: clerkName, clerkSalary
View'ı Sorgulamak
View, normal tablo gibi sorgulanır. İçine fonksiyon, JOIN vs. ekleyerek kullanıcıya tam ihtiyacı olan veriyi sunar.
-- View üzerinden sorgu SELECT ename FROM Clerk WHERE sal > 1000; -- Bu sorgu şuna eşdeğerdir: SELECT ename FROM emp WHERE job = 'CLERK' AND sal > 1000;
View'ı Güncellemek (DML İşlemleri)
Bazı view'lar güncellenebilirdir. View üzerindeki DML işlemi doğrudan altındaki tabloya yansır.
Güncellenemeyen View Koşulları
Şu yapıları içeren view'lar güncellenemez:
-- Güncellenebilir Clerk view'ı (empno dahil) CREATE VIEW Clerk AS SELECT empno, ename, job, sal FROM emp WHERE job = 'CLERK'; INSERT INTO Clerk VALUES (1234, 'SUE', 'CLERK', 8000); -- emp tablosuna da eklenir!
-- View üzerinden silme → emp tablosundan da silinir DELETE FROM Clerk WHERE ename LIKE '%MS%'; -- View üzerinden güncelleme → emp tablosunda güncellenir UPDATE Clerk SET sal = 1000 WHERE ename = 'JAMES';
WITH READ ONLY — Salt Okunur View
DML işlemlerinin (INSERT, UPDATE, DELETE) yapılmasını engelleyen view'lardır.
CREATE VIEW Manager AS SELECT empno, ename, sal FROM emp WHERE job = 'MANAGER' WITH READ ONLY; -- Hata verir: ORA-42399 DELETE FROM Manager WHERE ename = 'JONES';
DROP VIEW — View Silme
DROP VIEW Clerk; -- Sadece view tanımı silinir, emp tablosu etkilenmez! -- Ancak DROP TABLE emp yapılırsa Clerk view'ı kullanılamaz hale gelir.
Trigger (Tetikleyici)
Triggers
Trigger Nedir?
Trigger, belirli bir olay gerçekleştiğinde otomatik olarak çalışan (ateşlenen) saklı PL/SQL birimidir. Kullanıcı müdahalesi gerektirmez.
TRIGGER trigger_name triggering_event [ trigger_restriction ] BEGIN triggered_action; END;
Trigger Olayları
| Olay Türü | Örnekler | Kullanım |
|---|---|---|
| DML Events | INSERT, UPDATE, DELETE |
Tablo üzerindeki veri değişiklikleri |
| DDL Events | CREATE, ALTER |
Şema değişikliklerini denetleme |
| System Events | Database startup/shutdown | Sistem başlatma/kapatma işlemleri |
| User Events | User login/logout | Oturum açma/kapama denetimi |
Oracle Trigger Kullanım Alanları
- İş Kuralı Zorunluluğu: UNIQUE, NOT NULL, CHECK ile tanımlanamayan karmaşık kurallar.
- Hata Önleme: Geçersiz işlemleri durdurar, veri kalitesini artırır.
- İstatistik Toplama: Tablo kullanım verilerini toplar.
- Otomatik Değer Hesaplama: Türetilen sütun değerlerini otomatik doldurur.
- Denetim (Audit): Güvenlik ve uyum için değişiklikleri kayıt altına alır.
Trigger Oluşturma Sözdizimi
CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE | AFTER} triggering_event [OF column_name] ON table_name [REFERENCING <old or new values alias list>] [FOR EACH ROW] [FOLLOWS | PRECEDES another_trigger] [ENABLE / DISABLE] [WHEN condition] DECLARE declaration statements BEGIN executable statements EXCEPTION exception_handling statements END;
| Parametre | Açıklama |
|---|---|
BEFORE | AFTER |
Trigger olaydan önce mi sonra mı çalışır? |
FOR EACH ROW |
Satır seviyesi trigger. Her etkilenen satır için çalışır. Yoksa statement seviyesidir. |
:new.column |
Yeni (girilecek veya güncellenecek) değer |
:old.column |
Eski (mevcut) değer |
WHEN condition |
Trigger'ın yalnızca belirli koşulda çalışması için filtre |
OR REPLACE |
Aynı adda trigger varsa üzerine yazar |
Örnek 1 — Otomatik Komisyon Hesaplama
Maaş güncellendiğinde yeni maaş 3000'den büyükse komisyonu eski maaşın %5'i olarak ayarla.
CREATE OR REPLACE TRIGGER CommUpdate BEFORE UPDATE OF sal ON emp REFERENCING old as oldrow new as newrow FOR EACH ROW WHEN (newrow.sal > 3000) BEGIN :newrow.comm := :oldrow.sal / 20; -- %5 komisyon END;
-- SMITH'in (7369) maaşını 3500'e yükselt UPDATE emp SET sal = 3500 WHERE empno = 7369; -- 3500 > 3000 koşulu sağlandığı için trigger çalışır -- comm = eski_maaş / 20 = 800 / 20 = 40 olarak ayarlanır
Örnek 2 — Maaş Derecesi Doğrulama
Eklenen veya güncellenen maaş, SALGRADE tablosundaki herhangi bir dereceyle eşleşmiyorsa hata fırlat.
CREATE OR REPLACE TRIGGER emp_salary_check BEFORE INSERT OR UPDATE OF sal ON emp FOR EACH ROW DECLARE sal_grade NUMBER; BEGIN SELECT grade INTO sal_grade FROM Salgrade WHERE :new.sal BETWEEN losal AND hisal; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20001, 'Salary does not match any defined grade.'); END;
CREATE OR REPLACE TRIGGER emp_salary_check BEFORE INSERT OR UPDATE OF sal ON emp FOR EACH ROW DECLARE grade_count NUMBER; BEGIN SELECT COUNT(grade) INTO grade_count FROM Salgrade WHERE :new.sal BETWEEN losal AND hisal; IF grade_count = 0 THEN RAISE_APPLICATION_ERROR(-20002, 'Salary does not match any defined grade.'); END IF; END;
-- KING'in (7839) maaşını 15000 yap → SALGRADE'de yok UPDATE emp SET sal = 15000 WHERE empno = 7839; -- HATA: 15000, SALGRADE tablosundaki hiçbir dereceyle eşleşmiyor (max 9999)
Örnek 3 — Denetim (Audit) Trigger'ı
EMP tablosunda UPDATE veya DELETE yapıldığında, yapılan işlemi bir denetim (audit) tablosuna kaydet.
CREATE TABLE audits ( audit_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, table_name VARCHAR2(255), transaction_name VARCHAR2(10), by_user VARCHAR2(30), transaction_date DATE );
CREATE OR REPLACE TRIGGER emp_audit_trg AFTER UPDATE OR DELETE ON emp FOR EACH ROW DECLARE l_transaction VARCHAR2(10); BEGIN -- İşlem türünü belirle l_transaction := CASE WHEN UPDATING THEN 'UPDATE' WHEN DELETING THEN 'DELETE' END; -- Audit tablosuna kayıt ekle INSERT INTO audits (table_name, transaction_name, by_user, transaction_date) VALUES ('EMP', l_transaction, USER, SYSDATE); END;
-- SMITH'in (7369) maaşını güncelle UPDATE emp SET sal = 2000 WHERE empno = 7369; -- audits tablosuna otomatik kayıt eklenir: -- table_name='EMP', transaction_name='UPDATE', by_user='HR', transaction_date=...
Kısıtlamalar (NOT NULL, UNIQUE, FK vs.) basit veri bütünlüğü kuralları için yeterlidir ve performanslıdır. Trigger'lar ise karmaşık iş kuralları, çapraz tablo kontrolleri, otomatik hesaplamalar ve denetim işlemleri için kullanılır. İkisi birbirini tamamlar.
Sınav Hazırlık ve Pratik
Öğrenilen tüm konuların pekiştirilmesi için kapsamlı sorular
Aşağıdaki sorular, daha önceki 12 bölümde anlatılan konuları kapsamakta olup, klasik sınav ve mülakat soruları tarzında hazırlanmıştır.
A. Açık Uçlu Soru ve Çözümleri
SELECT ename, sal FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);
SELECT d.dname, COUNT(e.empno) FROM dept d LEFT JOIN emp e ON d.deptno = e.deptno GROUP BY d.dname;
SELECT e.ename AS "Çalışan", m.ename AS "Yönetici" FROM emp e LEFT JOIN emp m ON e.mgr = m.empno WHERE e.sal > (SELECT AVG(sal) FROM emp);
SELECT DISTINCT d.loc FROM emp e JOIN dept d ON e.deptno = d.deptno WHERE e.ename LIKE '%A%';
SELECT dname FROM dept WHERE deptno NOT IN (SELECT DISTINCT deptno FROM emp WHERE deptno IS NOT NULL);
SELECT s.grade, COUNT(e.empno) FROM emp e JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal GROUP BY s.grade;
SELECT * FROM ( SELECT ename, hiredate FROM emp ORDER BY hiredate DESC ) WHERE ROWNUM <= 3;
SELECT e.ename, e.sal, e.deptno FROM emp e WHERE e.sal > (SELECT AVG(sal) FROM emp WHERE deptno = e.deptno);
SELECT ename, sal FROM emp WHERE sal > ANY ( SELECT sal FROM emp JOIN dept ON emp.deptno = dept.deptno WHERE dname = 'SALES' );
CREATE OR REPLACE TRIGGER trg_check_sal BEFORE INSERT OR UPDATE ON emp FOR EACH ROW BEGIN IF :NEW.sal < 0 THEN RAISE_APPLICATION_ERROR(-20001, 'Maaş negatif olamaz'); END IF; END;
B. Çoktan Seçmeli Test
NULL değerleri başka bir değere çevirmek için kullanılır?💡 Cevabı Göster
NVL(sütun, deger) şeklinde
kullanılır ve NULL
olan veriyi belirtilen değere dönüştürür.GROUP BY kullanılan bir sorguda, grupların sonuçlarına göre filtreleme yapmak için
hangi
ifade kullanılır?💡 Cevabı Göster
Grup fonksiyonları (
SUM,
COUNT, AVG vb.) WHERE
ile kullanılamaz, gruplandırılmış veriyi filtrelemek için HAVING gereklidir.
SELECT COUNT(COMM) FROM EMP; sorgusu neyi döndürür?💡 Cevabı Göster
COUNT(sütun_adi) ifadesi, o
sütundaki NULL
OLMAYAN satırları sayar. Tüm satırları saymak için COUNT(*) kullanılır.WHERE ename LIKE '_A%' koşulu ne anlama gelir?💡 Cevabı Göster
Alt çizgi (_) tek bir karakteri temsil eder, yüzde (%) ise sıfır veya daha fazla karakteri temsil eder.
_A% ifadesi "ilk karakter
herhangi bir
şey, ikinci karakter A ve sonrası herhangi bir şey" demektir.NULL
değerlere izin verir?
💡 Cevabı Göster
UNIQUE kısıtlaması tekrarlı
(mükerrer) değere
izin vermez fakat birden fazla satırda NULL değer bulunabilir. PRIMARY KEY
ise NULL'a kesinlikle izin
vermez.SELECT * FROM A CROSS JOIN B;
sorgusu kaç
satır döndürür?💡 Cevabı Göster
Cross join (Kartezyen çarpım) tabloların tüm olasılıklarını birbirleriyle eşleştirir, yani satır sayıları çarpılır (5 x 4 = 20).
INSERT, UPDATE) yapmak için view'in
hangi özelliğe sahip
olması şart DEĞİLDİR?💡 Cevabı Göster
ORDER BY, view içindeki verilerin
sadece
görüntüleme sırasını değiştirir ve DML işlemlerini engellemez. Ancak GROUP BY veya
DISTINCT gibi
özet/gruplama operasyonları view üzerinden DML (Veri manipülasyonu) yapılmasını engeller.
AFTER INSERT) çalışan Trigger'ın içinde
:NEW.sütun = deger;
ataması yapılırsa ne olur?
💡 Cevabı Göster
AFTER trigger'larında
:NEW değerleri
değiştirilemez, sadece okunabilir. Yeni değer üzerinde manipülasyon yapmak isteniyorsa
BEFORE trigger
kullanılmalıdır.
💡 Cevabı Göster
Oracle'da tarih/zaman için
DATE
veya
TIMESTAMP kullanılır. DATETIME daha çok SQL Server (T-SQL) ve MySQL gibi
sistemlerde bulunur.
SELECT DECODE(deptno, 10, 'A', 20, 'B', 'C') FROM emp; ifadesi SQL
standartlarındaki hangi
ifadeyle eşdeğerdir?💡 Cevabı Göster
DECODE, Oracle'a özgü bir
fonksiyondur ve SQL
standartlarındaki CASE WHEN yapısının daha kısa halidir.SQL Kapsamlı Konu Anlatımı • Oracle SQL Tabanlı • EMP / DEPT / SALGRADE Örnek Veritabanı
13 Konu • Temel SELECT'ten Trigger'lara • Tüm Egzersiz ve Çözümler Dahil