13 Aralık 2013 Cuma

Global Temporary Tables GTT

ORACLE'in geçici kayıt tutmak için sunduğu bir tablo yapısı var. Bu tablo bir kez yaratılıyor. Bundan sonra ister kodun içinden ister TOAD gibi aracın içinden ORACLE'a bağlanın, bu tabloya yazdığınız kayıtları sadece siz görüyorsunuz. Kod bloğunuzda veya TOAD'ın içinden COMMIT veya ROLLBACK yaptığınızda tablo yazdığınız kayıtların ömrü bitmiş oluyor. ORACLE'ın  bizim yerimize bu tabloya sessionID diye bir sütun açtığını ve bu tabloya gelen okuma yazma sorgularının başına bu kuralan bağlantının (session'ın) Id^sini yazdığımızı düşünebiliriz.

Ne gibi problemlerin üzerinden gelmek için bu yaklaşımı kullanabiliriz?  (Bu amaçla yarattığımız tablonun adının PARAMETER_TABLE_GTT olduğunu düşünelim)

Rapor sorgusunu yazarken, raporu çalıştırdığımız parametleri Rapor sorgurunu içine  = :KUMPANYA_ID veya IN :KUMPANYA_ID_LIST diye ekleriz.  Rapor çalıştığında bizim parametrelerimiz, sorgu betiği içinde bunlarla yer değiştirir ve orjinalinde sanki bizim gönderidğimiz değerler varmış gibi çalışır. View içine parametre geçmek diye tabir edebileceğimiz bu yaklaşımı,  istediğimiz parametleri PARAMETER_TABLE_GTT kayıt ederek ve orijinal sorgumuzu bu tabloya join yaparak gerçekleştirebiliriz.

Kod içinden elde ettiğimiz ve başka bir sorgunun WHERE kısmına  IN ile eklemek istediğimiz değerleri bu tabloya yazarak, orijinal sorgumuzda bu tabloya exist olarak ekleyebiliriz.

Ayrıntılı bilgiye buradan ulaşabilirsiniz.


Örnek bir kullanımın adımları

Tablo Yaratılması  (Bir kez yapılacak bir işlemdir)

DROP TABLE YNA.PARAMETER_TABLE_GTT CASCADE CONSTRAINTS;

CREATE GLOBAL TEMPORARY TABLE YNA.PARAMETER_TABLE_GTT
(
  NUMBER_ALAN1  NUMBER
)
ON COMMIT DELETE ROWS
RESULT_CACHE (MODE DEFAULT)
NOCACHE;

GRANT DELETE, INSERT, SELECT, UPDATE ON YNA.PARAMETER_TABLE_GTT TO ORACLEREADERUSER;


View içinde kullanımı
DH_DA_GOP_SEF_KUMP_DA_VW tablosunda LEFT JOIN veirilmiş bir alt sorgunun içinde kullanılıyor. Bu alt sorgunun (aslında diğer tablolar ile bağlantısını bir alan üzerinden kuramadığımız) sadece istediğimiz parametre için çalışmasını istiyoruz.
..
..
(
..
  FATURA , DH_DA_SEFER_KUMPANYA ,
                             PARAMETER_TABLE_GTT GTT
                       WHERE    
                              DH_DA_SEFER_KUMPANYA.KUMPANYA_ID = GTT.NUMBER_ALAN1


Kod içerisinden çağırımı

            TransactionHelper txnHelper = new TransactionHelper();
            txnHelper.BeginTransaction();
            try
            {
                //txnHelper yaşamı boyunca geçici kayıt (ParameterTableGttEntity) tablosuna bir kayıt atıyor.
                //DhDaGopSefKumpDaVwCollection içinde bu tabloya JOIN atılıyor. View içine parametre geçmek için yazıldı.
                var prmTableGttEntity = new ParameterTableGttEntity();
                txnHelper.AddElementToTransaction(prmTableGttEntity);
                prmTableGttEntity.NumberAlan1 = request.KumpanyaId;
                prmTableGttEntity.Save();
                TypedListBuilder tlb = new TypedListBuilder();
                tlb.addFields(DhDaGopSefKumpDaVwFields.DaGopSeferLokasyonId, DhDaGopSefKumpDaVwFields.DaGopSeferLokasyonId.Name);
                tlb.addFields(DhDaGopSefKumpDaVwFields.DaKumpanyaId, DhDaGopSefKumpDaVwFields.DaKumpanyaId.Name);
                tlb.addFields(DhDaGopSefKumpDaVwFields.DaNo, DhDaGopSefKumpDaVwFields.DaNo.Name);
                
                //Veri çektiğimiz yapıda aynı Transaction'i kullanmalıyız.
                response.DhDaSeferKumpanyaDT = tlb.Fill(filtre, sortExpression, TxnHelper);
                //Tabloya attığımız kayıt bu noktada silindi.
                txnHelper.CommitTransaction();
            }
            catch (Exception)
            {