ORACLE PL/SQL OBJECT TYPE 6 SELECT * FROM TABLE(

Söz ve ibareler, dinleyenler topluluğu için azık mesabesindedir.

Senin o azıktan nasibin ancak yediğin kadarıdır –İbni Arabi

 

Merhaba Arkadaşlar
object oriented programming oracle makalemize devam ediyoruz. (Bu işi sevdim, Yazıp duruyorum)
Bu makalemizde, bir object type oluşturacağız, bu object type”ı referans alan bir type list oluşturacağız.
Bir function ile bu listeyi doldurup geri donmesini saglayacagiz.
Bunun bize ne avantajı olacak peki:
cevap: bu function”ı tablo gibi kullanıp, select sorguları icerisine alabilecegiz;
bu sayede tablo veya view gibi dinamik bir kullanım saglayacak.
Sözü fazla uzatmadan; bunların nasıl yapılacağını anlatalım.
Önce type”ımızı create ediyoruz.

--
--
create or replace type t_key_value as object 
(
  key         varchar2(1000),
  value       varchar2(4000),
  type        varchar2(100),
  constructor function t_key_value(key varchar2, value varchar2) return self as result
);
/
--
--

type”ın body kısmını create ediyoruz. ve default constructor tanımlayıp,
cumartesi ve pazar günlerini tatil diye işaretlemesini saglayacagiz.

--
--
create or replace type body t_key_value is
  constructor function t_key_value(key varchar2, value varchar2) return self as result is
  begin
  
    if key in (6, 7) then
      self.type := 'Tatil';
    else
      self.type := 'İş Günü';
    end if;
    
    self.key   := key;
    self.value := value;
    return;
  end;
end;
/
--
--

Type”ımızı referans alan object type list tanımlamasını da yapalım.

--
--
create or replace type t_key_value_list as table of t_key_value;
/
--
--

evet artık isi yapacak function”ı da olusturalım.
kodun icine comment yazarak her satırı acıklamaya özen gösteriyorum.

--
--
create or replace function getKeyValueList return t_key_value_list is
  v_kv      t_Key_Value; -- oncelikle type degiskenimizi tanımlıyor
  v_kv_list t_key_value_list := t_key_value_list(); -- key value type'ının listesini olusturmustuk onu tanımlıyoruz
  v_day     varchar2(10) := null; -- gunlerin isimlerini tutabilmek icin ayrı bir degisken tanımladık case fonksiyonu ile buna deger atayacağız
begin
  -- WRITE TYPE
  -------------------------------------------------
  -- Yedi kez donecek bir for döngüsü oluşturuyoruz
  --dbms_output.put_line('------ Deger Atama  ------');
  for r in 1 .. 7 loop
    ------------------------
    -- gelen degere gore gunun ismi ilgili degiskene atilacak
    case r -- r for dongusundeki donus degerini alır o yüzden ayrıca bir degisken tanımlamaya gerek yok
      when 1 then
        v_day := 'PAZARTESI';
      when 2 then
        v_day := 'SALI';
      when 3 then
        v_day := 'CARSAMBA';
      when 4 then
        v_day := 'PERSEMBE';
      when 5 then
        v_day := 'CUMA';
      when 6 then
        v_day := 'CUMARTESI';
      when 7 then
        v_day := 'PAZAR';
      else
        v_day := null; -- olmaz ama her zaman siz kodunuzu yazarken ELSE'yi düşünün ve yazın...
    end case;
    ------------------------
  
    -- oncelikle type degiskenimi dolduruyoruz....  
    /*
    v_kv.key   := r;
    v_kv.value := v_day;
    */
    -- constrotur devreye girsin diye new kewwordunu kullandim... 
    -- yukarıdak remark'ladıgım gibi kullansak ve declare kısmında initialize etseydik bu asamada constructor devreye girmezdi. 
    -- ilk ne zaman initialize edildiyse, constructor o zaman devreye girer.
    v_kv := new t_Key_Value(r, v_day);
    ------------------------
    -- object type listimizi extend edip, içine type basacağız. 
    v_kv_list.extend;
    v_kv_list(v_kv_list.count) := v_kv; -- index vererek type'ı refere ediyoruz.
    ------------------------

  end loop;

  -- buraya kadar type'ı doldurduk ve type list'imize bu type'ları ekledik.
  -- bundan sonra artık; olusturdugumuz type list'i function'dan geri donecegiz
  return v_kv_list;


end getKeyValueList;
/
--
--

 

tanımlamalarımız tamam. Artık bunları kullanalım. Buyurun size bir kaç tane örnek. Bundan sonrasını sizin haya gücüne bırakıyorum. istediğiniz gibi kullanın…

Capture

--
-- diğer bir kullanım 

select * from table(getKeyValueList) a where a.type='İş Günü';

select * from table(getKeyValueList) a where a.type='Tatil';
--
--

 

Selam ve Dua ile…

@Cevheri

 

 

ORACLE PL/SQL – OBJECT TYPE – 5 USING INSERT INTO

Hırsı bırak, kendini boş yere harcama.
Şu toprak altında çırak da bir, usta da –Mevlana

Merhaba Object Oriented Oracle yazımıza devam ediyoruz.

Bu yazımızda, object type’ları tabloya veya tablonun column’larına referans verme ve buralara, kayıt ekleme ile ilgili çok güzel örnekler yapacağız. Program yazarken oluşturduğunuz ve kullandığımız tipleri, hiç bir tip dönüşümüne sokmadan, olduğu gibi veritabanına kaydedip, okumaya başlayınca, Objelerle çalışmanın lezzetini tadacaksınız.

Öncelikle personType ve personInventory diye iki tane obje oluşturuyorum. birinde personel bilgileri, diğerinde, personel envanter bilgileri. Personel ve Envanter içeriği(özelliği) çok sık değişmeyeceği için, tüm ihtiyaç olacak alanlar oluşturup, bunları column tipi olarak vereceğiz.

Tip ve tablomuzu oluşturalım.

Person Bilgileri Object Type:

-- person icin uygun object type oluşturulur..
create or replace type personType as object
(
  firstname varchar2(100),
  lastname  varchar2(100),
  mail      varchar2(100),
  phone     varchar2(20)
)
;
/

Person Envanter Bilgisi Object Type:

-- personel envanteri icin uygun type oluşturulur.
create or replace type personInventory as object
(
  inventoryname varchar2(100),
  inventorytype varchar2(20)
);
/

Şimdi de bu type’ları referans alan tablomuzu oluşturalım:

-- person icin tabloyu object type'larımızla create ediyoruz
-- direk o tipleri insert edeceğiz.
create table personTab (
person       personType,
invontory    personInventory
);

Eveet yukarda gördüğünüz gibi; tablomuzun iki kolonu var; ama içlerinde onlarca, yüzlerce özellik olabilir. Peki güzel, iyi be kardeşim bunu biz nasıl kullanacağız, hadi, insert ve select deneyelim.(sanki okuyanlar hiç select-insert bilmiyor ya…)

insert into personTab values (
personType('Ali','Sormaz','ali@sormaz.com','02122122112'),
personInventory('Bilgisayar', 'TEKNIK')
);

insert into personTab values (
personType('Veli','Yormaz','veli@yormaz.com','3122122112'),
personInventory('Paspas', 'TEMIZLIK')
);

commit;

Evet dediğiniz gibi insertin hiç farkı yok, aslında şuna benzer : insert into table_name select * from filanca_table;

son bombamızı patlatıp, select sorgumuzu da yazıyoruz…………

Capture

Sorgu sonucuna dikkat ettiyseniz, bir kişinin adını çekmek istiyorsak = personTab.Person.Firstname şeklinde bir tree yapısı kuracağız. bu tree yapısı istediğiniz kadar içeri gidebilir.

Object Type’ların tablolarla ilişkisini inceleyemeye çalıştık; bu konuda makalelerimiz devam edecek. Dilimiz döndüğünce, parmaklarımız yazdığınca bu konuları anlatmaya çalışacağız.

Selam ve Dua ile…

 

ORACLE PL/SQL – OBJECT TYPE – 4 USING INHERITANCE

Misafirsin Bu Hanede Ey Gönül,
Umduğunla Değil , Bulduğunla Gül..
Hane Sahibi Ne Derse O Olur,
Ne Kimseye Sitem Eyle , Ne de Üzül –Mevlana

Merhaba Dostlar

Object – Oriented Oracle konumuzun dördüncü makalesindeyiz. Bu makalede sizlere, OOP programlamanın olmazsa olması inheritance (kalıtım, miras alma) özelliğinin plsql de nasıl kullanılacağını anlatacağım. Buraya kadar anlattığımız makaleler daha basic konulardı, artık object type’ın enterprise özelliklerini incelemeye başlıyoruz.  Burada OOP nin inheritance özelliğini açıklamaya kalkmayacağım. bunu bildiğinizi varsayıyorum. (Buradan inceleyebilirsiniz)

Bu yazımda, mesaj yapısı kurdum. bir BaseMessage type’ım var. Bu type bir mesaj’da olmazsa olmaz özellikleri(en base) barındıracak; ancak bundan, hata mesajı ve başarılı mesaj gibi iki tane daha type türeteceğiz. Base type’ta print diye bir metod var, doldurulan mesaj içeriklerini ekrana yazdıran metod. bu metodu, hem başarılı mesaj, hemde hata mesajlarına tek tek yazmıyoruz. Base type’ta yapmamız yeterli.

Miras alma UNDER keywordü ile yapılmaktadır. aşağıda örneğimizde görülecektir.

Şimdi objelerimi create edelim sırasıyla

Önce Base Type’ı create edelim. İçinde iki tane constructor var.  Bu constructor’ların amacı, bu objeleri, istersek parametre vererek, istersekte, parametre vermeden çağrılabilmesini sağlamaktır.

SuccessMessage();

SuccessMessage(mesajkodu, mesajicerigi);

Not: create ederken force keywordunu kullandım. bunun amacı, bu objeyi referans alan başka objeler varsa, replace etmeye kalktığınızda uyarı verir. yani en alttaki oğul kaydı droplanmadan, üstteki obje değiştirilemez(spec tarafı). body kısmında böyle bir kısıt yok.

create or replace type BaseMessageType force as object
(
  Code    varchar2(20),
  Message varchar2(4000),
  constructor function BaseMessageType return self as result,
  constructor function BaseMessageType(p_code varchar2, p_message varchar2) return self as result,
  member procedure print
)
not final -- Miras alınabilecek bir type oluşturmuş olduk
/

create or replace type body BaseMessageType is

  -- ilk deger ataması default degerler ile yapılıyor.
  constructor function BaseMessageType return self as result is
  begin
    self.Code    := '00000';
    self.Message := 'NULL';
    return;
  end;

  -- parametre olarak gelenler code ve message kısmına atanıyor
  constructor function BaseMessageType(p_code varchar2, p_message varchar2) return self as result is
  begin
    self.Code    := p_code;
    self.Message := p_message;
    return;
  end;
  member procedure print is
  begin
    dbms_output.put_line('Mesaj Kodu  :' || self.Code);
    dbms_output.put_line('Mesaj Icerik:' || self.Message);
  end;
end;
/

Başarılı Message Type’ı oluşturalım. code , message ve print özelliklerini base’den alacak şekilde tasarlıyoruz.

create or replace type SuccessMessage under BaseMessageType
(
  -- normalde mesaj tipini de  base type'ta tanımlayabilirdik; ama burda da bir property olsun istedim.
  MessageType varchar2(20),
  constructor function SuccessMessage return self as result,
  constructor function SuccessMessage(p_code varchar2, p_message varchar2) return self as result
)
/

create or replace type body SuccessMessage is

  constructor function SuccessMessage return self as result is
  begin
    self.MessageType    := 'SUCCESS';
    self.Code           := '00001';
    self.Message       	:= 'SUCCESSFUL';
    return;
  end;

  constructor function SuccessMessage(p_code varchar2, p_message varchar2) return self as result is
  begin
    self.MessageType    := 'SUCCESS';
    self.Code           := p_code;
    self.Message        := p_message;
    return;
  end;

end;
/

Aynı mantıkla Hata Mesajı Type’ımızıda oluşturalım

create or replace type ErrorMessage under BaseMessageType
(
  -- normalde mesaj tipini de  base type'ta tanımlayabilirdik; ama burda da bir property olsun istedim.
  MessageType varchar2(20),
  constructor function ErrorMessage return self as result,
  constructor function ErrorMessage(p_code varchar2, p_message varchar2) return self as result
)
/
create or replace type body ErrorMessage is

  constructor function ErrorMessage return self as result is
  begin
    self.MessageType    := 'ERROR';
    self.Code           := '00003';
    self.Message        := 'GENERAL ERROR';
    return;
  end;

  constructor function ErrorMessage(p_code varchar2, p_message varchar2) return self as result is
  begin
    self.MessageType    := 'ERROR';
    self.Code           := p_code;
    self.Message        := p_message;
    return;
  end;

end;
/

BaseMessageType oluşturduk,

SuccessMessage ve ErrorMessage bundan türedi. ve üst objenin tüm özelliklerini kullanabilecek hale geldi.

şimdi örnek kodumuzu yazalım. yani bunları çalıştıralım. ve bakalım nasıl bir output ortaya çıkacak.

Not : print kullanımına dikkat edelim.

Tabi iserror diye bir değişken tanımladım. amaç program içinde hata oluştuğunda bunu setleyeceğim ve buna göre uygun message’ı çağıracağım.

-- Created on 20.05.2015 by cevheri 
declare
  error   ErrorMessage;
  succes  SuccessMessage;
  iserror boolean := true;
begin

  -- Hayal gucumuzu kullanarak;
  -- burada zilyon tane(baya bi çok demek) 
  -- iş yapan kod calıştığını düşünüyoruz
  -- hata oluşmassa burası çalışacak
  if iserror then
  
    -------------------------------------------------------------------------
    dbms_output.put_line('----------------------------');
    dbms_output.put_line('Hata yok default başarılı mesajı dönsün');
  
    -- type'ımızda constructor olduğu için
    -- default değerleri kullacağız
    succes := SuccessMessage;
    succes.print;
  
    dbms_output.put_line('----------------------------');
    dbms_output.put_line('Hata yok, Kullanıcıya Afferin desin');
  
    -- type'ımızda constructor olduğu için
    -- parametre almasını sağlayacağız
    succes := SuccessMessage('00001', 'Afferin Güzel Çalıştırdın');
    succes.print;
    -------------------------------------------------------------------------
  end if;

  iserror := false; -- artık hata yok 🙂 düzeldi
  if (not iserror) then
    
    -------------------------------------------------------------------------
    -- Yine Hayal gucumuzu kullanarak;
    -- burada zilyon tane(baya bi çok demek) 
    -- iş yapan kod calıştığını ve hata meydana geldiginde de 
    -- bu satırın çalışacağını düşünüyoruz.
    
    dbms_output.put_line('----------------------------');
    dbms_output.put_line('Hata oluştuğunu anlayalım yeter');
    error := ErrorMessage;
    error.print;
  
    dbms_output.put_line('-------------------------------------');
    dbms_output.put_line('Hatanın sebebini biliyoruz. Yakaladık');
    error := ErrorMessage('00002', 'Tabloya kayıt eklenirken Hata olustu.');
    error.print;
    -------------------------------------------------------------------------
  end if;

end;
/

Şimdi de çıktısına bir göz atalım mı
——————————————————————-

mesaj, dışardan parametre vermeden çağrıldığında
Hata yok default başarılı mesajı dönsün
Mesaj Kodu :00001
Mesaj Icerik:SUCCESSFUL
——————————————————————-

mesaj ve code, dışardan parametre verilerek çağrılırsa
Hata yok, Kullanıcıya Afferin desin
Mesaj Kodu :00001
Mesaj Icerik:Afferin Güzel Çalıştırdın
——————————————————————-

mesaj, dışardan parametre vermeden çağrıldığında
Hata oluştuğunu anlayalım yeter
Mesaj Kodu :00003
Mesaj Icerik:GENERAL ERROR
——————————————————————-
mesaj ve code, dışardan parametre verilerek çağrılırsa
Hatanın sebebini biliyoruz. Yakaladık
Mesaj Kodu :00002
Mesaj Icerik:Tabloya kayıt eklenirken Hata olustu.
——————————————————————-

Bu örnek daha spesific yapılabilir. Yağ-Salça-Soğan bizden, siz isterseniz içine patates, patlıcan vb… ne katarsanız katın.

Ben en basit şekliyle, sade ve anlaşılır olmasına özen gösteriyorum. sizden yapmanızı istediğim ilk örnek, şudur: success mesaj ve error message type’larının içindeki constructor’larının içinde kod yazmayın. base’e gidip, message’ın nerden geldiğini anlayın ve tüm kodlamayı ordan yapın. (ödev de verirmişiz ya…)

Selam ve Dua ile…

ORACLE PL/SQL – OBJECT TYPE – 3 USING PL/SQL OBJECT TYPE “CONSTRUCTOR”

Her canlının ölümü tadacağını,
ama sadece bazılarının hayatı tadacağını öğrendim. — Mevlana

 

Merhaba

Bir önceki yazımızda, object type ve object type list örneğini inceledik.(Buradan inceleyebilirsiniz)

Artı Bu yazımızda, biraz daha işi profesyonelleştirelim ve  aynı örneği kullanarak, object type’lar içine constructor tanımlaması yapalım mı. Bu yapıyı oracle PL/SQL dilinde ilk duyanlar, hadi yaaa derler genelde. Çünkü bir veritabanından, object oriented çalışma mantığı pek beklemezler. ama ilk object type yazımızda da bunu anlatmaya çalışmıştım(Buradan inceleyebilirsiniz) . ilk iki yazı standart bir tip tanımlaması ve array mantığında, o tipten liste oluşturma şeklinde oldu. artık bu object type’lar içinde çok güzel programlar yazağız.

Muhabbeti uzatmıyor ve sizi kodla baş başa bırakıyorum.

hadi artık objemizi create edelim

create or replace type t_key_value as object 
(
  key         varchar2(1000),
  value       varchar2(4000),
  type        varchar2(100),
  constructor function t_key_value(key varchar2, value varchar2) return self as result
);
/

create or replace type body t_key_value is
  constructor function t_key_value(key varchar2, value varchar2) return self as result is
  begin
  
    if key in (6, 7) then
      self.type := 'Tatil';
    else
      self.type := 'Calismak Lazim';
    end if;
    
    self.key   := key;
    self.value := value;
    return;
  end;
end;
/

create or replace type t_key_value_list as table of t_key_value;
/

 

Bu kod şunu yapıyor: günleri ve günün numarasını tutup, bunu listelemeye yarıyor. günlerin yüklemesi yapılırken,” tatil mi, çalışma zamanı mı olduğuna karar veriyor.”

Kodu satır satır anlatmaya çalıştm.

Kolay gele.

-- Created on 14.05.2015 by Cevheri 
declare
  v_kv      t_Key_Value; -- oncelikle type degiskenimizi tanımlıyor ve initialize ediyorduk artık yapmıyoruz :)))
  v_kv_list t_key_value_list := t_key_value_list(); -- key value type'ının listesini olusturmustuk onu tanımlıyoruz
  v_day     varchar2(10) := null; -- gunlerin isimlerini tutabilmek icin ayrı bir degisken tanımladık case fonksiyonu ile buna deger atayacağız
begin

  -- WRITE TYPE
  -------------------------------------------------
  -- Yedi kez donecek bir for döngüsü oluşturuyoruz
  dbms_output.put_line('------ Deger Atama  ------');
  for r in 1 .. 7 loop
    ------------------------
    -- gelen degere gore gunun ismi ilgili degiskene atilacak
    case r -- r for dongusundeki donus degerini alır o yüzden ayrıca bir degisken tanımlamaya gerek yok
      when 1 then
        v_day := 'PAZARTESI';
      when 2 then
        v_day := 'SALI';
      when 3 then
        v_day := 'CARSAMBA';
      when 4 then
        v_day := 'PERSEMBE';
      when 5 then
        v_day := 'CUMA';
      when 6 then
        v_day := 'CUMARTESI';
      when 7 then
        v_day := 'PAZAR';
      else
        v_day := null; -- olmaz ama her zaman siz kodunuzu yazarken ELSE'yi düşünün ve yazın...
    end case;
  
    ------------------------
    -- !!!! ÖNEMLİ !!!!!!!!
    -- işte olay burada kopuyor. ilk değer ataması yapılırken, constructor da çalışmasını yapıyor.
    v_kv := new t_Key_Value(r, v_day);
    ------------------------
  
    -- object type listimizi extend edip, içine type basacağız. 
    v_kv_list.extend;
    v_kv_list(v_kv_list.count) := v_kv; -- index vererek type'ı refere ediyoruz.
    ------------------------
  
    dbms_output.put_line('Atanan Key         :' || v_kv.key);
    dbms_output.put_line('Atanan Value       :' || v_kv.value);
    dbms_output.put_line('constructor type   :' || v_kv.type);
    dbms_output.put_line('****');
  end loop;

  dbms_output.put_line('-----------------------------');
  -- END WRITE-------------------------------------

  --**************************************************************

  -- READ TYPE-------------------------------------

  v_kv := null;
  dbms_output.put_line('-------  Deger Okuma   ------');
  -- hadi artık, doldurulan listelerin içindeki değerleri okuyalım
  for r in 1 .. v_kv_list.COUNT loop
  
    v_kv := v_kv_list(r); --- yine index vererek okuyoruz....
  
    dbms_output.put_line('Okunan Key         :' || v_kv.key);
    dbms_output.put_line('Okunan Value       :' || v_kv.value);
    dbms_output.put_line('constructor type   :' || v_kv.type);
    dbms_output.put_line('****');
  end loop;

  dbms_output.put_line('----------------------------');
  -- END READ-------------------------------------

end;

 

 

Kodun bendeki çıktısı şu şekilde, bir de siz deneyin bakalım doğru çalışıyor mu …….

------ Deger Atama  ------
Atanan Key         :1
Atanan Value       :PAZARTESI
constructor type   :Calismak Lazim
****
Atanan Key         :2
Atanan Value       :SALI
constructor type   :Calismak Lazim
****
Atanan Key         :3
Atanan Value       :CARSAMBA
constructor type   :Calismak Lazim
****
Atanan Key         :4
Atanan Value       :PERSEMBE
constructor type   :Calismak Lazim
****
Atanan Key         :5
Atanan Value       :CUMA
constructor type   :Calismak Lazim
****
Atanan Key         :6
Atanan Value       :CUMARTESI
constructor type   :Tatil
****
Atanan Key         :7
Atanan Value       :PAZAR
constructor type   :Tatil
****
-----------------------------
-------  Deger Okuma   ------
Okunan Key         :1
Okunan Value       :PAZARTESI
constructor type   :Calismak Lazim
****
Okunan Key         :2
Okunan Value       :SALI
constructor type   :Calismak Lazim
****
Okunan Key         :3
Okunan Value       :CARSAMBA
constructor type   :Calismak Lazim
****
Okunan Key         :4
Okunan Value       :PERSEMBE
constructor type   :Calismak Lazim
****
Okunan Key         :5
Okunan Value       :CUMA
constructor type   :Calismak Lazim
****
Okunan Key         :6
Okunan Value       :CUMARTESI
constructor type   :Tatil
****
Okunan Key         :7
Okunan Value       :PAZAR
constructor type   :Tatil
****
----------------------------

 

 

Selam ve Dua ile

CASE FONKSİYONU

CASE fonksiyonu, sql sorgusu içinde koşullu sorgulama yapılmasına imkan tanımaktadır ve IF-THEN-ELSE işlevselliğine sahiptir. Oracle 9i versiyonundan itibaren kullanılabilmektedir.

Söz dizimi aşağıdaki gibidir.

CASE WHEN koşul1 THEN sonuc 
     WHEN koşul2 THEN sonuc
     ...
     ELSE sonuc 
END

Örnek;

-- Tablomuzu oluşturuyoruz
Create table Notlar(ogrenci_no number, ders_adi varchar2(50), notu number);

-- Tabloya örnek kayıtlar ekliyoruz
insert into Notlar (ogrenci_no, ders_adi, notu) values (1, 'Matematik', 4);
insert into Notlar (ogrenci_no, ders_adi, notu) values (1, 'Fizik', 5);
insert into Notlar (ogrenci_no, ders_adi, notu) values (1, 'Edebiyat', 1);
insert into Notlar (ogrenci_no, ders_adi, notu) values (1, 'Resim', 3);

-- Sorgumuz
SELECT ogrenci_no, ders_adi, notu, 
  CASE WHEN notu < 2  THEN 'Bu dersi yeniden almalısınız.' -- Notu 2'den küçükse
       WHEN notu between 2 and 3 THEN 'Daha çok çalışmalısınız.' -- Notu 2 ile 3 arasında ise (2 ve 3 dahil)
       WHEN notu = 4 THEN 'Başarılısınız.' -- Notu 4'e eşit ise
       WHEN notu > 4 THEN 'Tebrikler.' -- Notu 4'ten büyükse
  ELSE 'Notunuzu Hesaplayamıyorum.' -- Notu koşullar dışındaysa
  END as Aciklama
FROM Notlar;