16 Ekim 2016 Pazar

Trigger'da Değişken Tanımlama ve İç İçe Döngü (PLPGSQL)



Hedef Tablo İçin Trigger Tanımlama:

- Aşağıda hedef tablo dediğimiz, hangi tablo üzerinde 'insert' veya 'update' yapıdığında trigger'in hangi fonksiyonu tetikleyeceği üzerinde değişiklik yapılacak tablo hedef tablo niteliğini almış olur.

CREATE TRIGGER stscmetrictarget_guncelle
  AFTER INSERT OR UPDATE
  ON STSCMETRICTARGET --- hedef tablo
  FOR EACH ROW                 ---- tetiklenecek fonksiyon hedef tablonun her satırı için geçerli olur
  WHEN (pg_trigger_depth()=0)

 EXECUTE PROCEDURE fonksupdate(); --- tetiklenecek olan fonksiyonun adı




Trigger'da İç İçe IF-ELSIF-ELSE-END Döngüsü ve Değişken Tanımlama




Trigger'da Değişken Tanımlama:

- PostgreSql'de yazdığımız trigger'da bazen değişken tanımlama gereksinimi duyarız, değişken tanımlama şekli aşağıdaki gibi olmalıdır:



CREATE OR REPLACE FUNCTION fonksupdate()
  RETURNS trigger AS
$BODY$

DECLARE a INTEGER; -- a,b ve c değişkenlerinin tamsayı değeri taşıyacağını gösterir.
DECLARE b INTEGER;
DECLARE c INTEGER;

BEGIN
--- 'Begin' den önce tanımlamış olduğumuz değişkenlere sql sorgudan değer ataması aşağıdaki gibi yapılır. Böylece sorgunun sonucu üstte tanımlanan değişkenlere aktarılmış olur.  
SELECT INTO a nrperiod from STSCMETRICTARGET where cdscmetric=8460 order by nryear,nrperiod desc limit 1;
SELECT INTO b nrperiod from STSCMETRICTARGET where cdscmetric=8462 order by nryear,nrperiod desc limit 1;
SELECT INTO c nrperiod from STSCMETRICTARGET where cdscmetric=8462 order by nryear desc limit 1;




Trigger'da İç İçe IF-ELSIF-ELSE-END Döngüsü:


BEGIN

IF ---koşul--- THEN
-------
ELSIF ---koşul--- THEN
-------
ELSE
IF ---koşul--- THEN
------
ELSE
------
END IF;
END IF;

END --- şeklinde yazılabilir.

- Algoritma mantığına göre üstteki sıra değişebilir ancak her 'if ' döngüsü için bir 'end if' yazmayı unutmamak gerekir. Aşağıdaki örnekte iç içe değil de farklı koşullar barındıran alt alta tanımlı IF-END IF bloklarından oluşan bir algoritma yer almaktadır.


BEGIN

IF ---koşul --- THEN
  IF ---koşul ---THEN
    ------------
  ELSE
    ------------
END IF;
END IF;

IF ---koşul --- THEN
  IF ---koşul ---THEN
    ------------
  ELSE
    ------------
END IF;
END IF;

END


- Döngüde yer alan a ve b değişkenlerine nasıl değer aktarıldığı yukarıdaki gibidir, tanımlanan bu değişkenlerin döngüde nasıl kullanıldığı ise aşağıdaki gibidir.


IF (a+1 = b) THEN --- PostgreSql'de = işareti karşılaştırma operatörü olarak eşitliği simgeler.

  IF (a+1 < 13) THEN

  UPDATE STSCMETRICTARGET SET VLACTUAL=AD.DVD FROM ((select CDSCMETRIC AS DV,NRPERIOD AS DVP,NRYEAR AS DVY, VLACTUAL AS DVD from STSCMETRICTARGET where cdscmetric=8460) A JOIN
 (select CDSCMETRIC AS DA,NRPERIOD AS DAP,NRYEAR AS DAAY, VLACTUAL AS DAD from STSCMETRICTARGET where cdscmetric=8462) B ON DAAY=DVY AND DVP+1=DAP) AD
  WHERE cdscmetric=8462 AND NRPERIOD=DVP+1 AND NRYEAR=DVY;

RETURN NULL;

EXIT; --- üstteki sql komutu işlendikten sonra döngüden çıkış sağlamak için exit; komutu kullanılır.


   ELSE

   UPDATE STSCMETRICTARGET SET VLACTUAL=AD.DVD FROM ((select CDSCMETRIC AS DV,NRPERIOD AS DVP,NRYEAR AS DVY, VLACTUAL AS DVD from STSCMETRICTARGET where cdscmetric=8460) A JOIN
 (select CDSCMETRIC AS DA,NRPERIOD AS DAP,NRYEAR AS DAAY, VLACTUAL AS DAD from STSCMETRICTARGET where cdscmetric=8462) B ON DAAY+1=DVY AND DAP=1) AD
  WHERE cdscmetric=8462 AND NRPERIOD=1 AND NRYEAR=NRYEAR+1;
RETURN NULL;

EXIT;
 
END IF; --- döngü sonu
END IF;

IF (a+1 <> b) AND (c <> 1) THEN --- PostgreSql'de eşitsizliği tanımlamak için <> veya != karşılaştırma operatörlerinden birini kullanabiliriz.
   IF (a+1 < 13) THEN

   INSERT INTO STSCMETRICTARGET (cdscmetrictarget,CDSCMETRIC,NRPERIOD, NRYEAR, VLWEIGHT, VLACTUAL) SELECT DISTINCT
(select cdscmetrictarget+1 from stscmetrictarget order by cdscmetrictarget desc limit 1) as cdscmetrictarget,
(select 8462 from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as CDSCMETRIC,
(select NRPERIOD +1 from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as NRPERIOD,
(select NRYEAR from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as NRYEAR,
(select VLWEIGHT from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as VLWEIGHT,
(select VLACTUAL from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as VLACTUAL
 FROM STSCMETRICTARGET where cdscmetric=8462 limit 1;
RETURN NULL;

EXIT;
ELSE

INSERT INTO STSCMETRICTARGET (cdscmetrictarget,CDSCMETRIC,NRPERIOD, NRYEAR, VLWEIGHT, VLACTUAL) SELECT DISTINCT
(select cdscmetrictarget+1 from stscmetrictarget order by cdscmetrictarget desc limit 1) as cdscmetrictarget,
(select 8462 from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as CDSCMETRIC,
(1) as NRPERIOD,
(select NRYEAR+1 from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as NRYEAR,
(select VLWEIGHT from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as VLWEIGHT,
(select VLACTUAL from stscmetrictarget where cdscmetric=8460 order by NRYEAR,NRPERIOD DESC LIMIT 1) as VLACTUAL
 FROM STSCMETRICTARGET where cdscmetric=8462 limit 1;
RETURN NULL;

EXIT;

END IF;
END IF;

IF (a+1 <> b) AND (c = 1) THEN

 UPDATE STSCMETRICTARGET SET VLACTUAL=AD.DVD FROM ((select CDSCMETRIC AS DV,NRPERIOD AS DVP,NRYEAR AS DVY, VLACTUAL AS DVD from STSCMETRICTARGET where cdscmetric=8460) A JOIN
 (select CDSCMETRIC AS DA,NRPERIOD AS DAP,NRYEAR AS DAAY, VLACTUAL AS DAD from STSCMETRICTARGET where cdscmetric=8462) B ON DAAY+1=DVY AND DAP=1) AD
  WHERE cdscmetric=8462 AND NRPERIOD=1 AND NRYEAR=NRYEAR+1;
RETURN NULL;

EXIT;
END IF;

END --- BEGIN sonu
$BODY$
  LANGUAGE plpgsql;

Hiç yorum yok:

Yorum Gönder