Home

Kaynakta Change Data Capture(CDC)’ye eklediğimiz bir tabloda yapılan fiziksel silme işlemi Journal tablosuna JRN_FLAG = ‘D’ olarak düşüyor ancak bunun hedefe yansıması IKM Oracle Incremental Update modülünü kullanırsanız yine fiziksel silme şeklinde oluyor, IKM Oracle Slowly Changing Dimension modülünü kullandığınız takdirde ise kaynakta silinen kayıtların hedefi etkilemediğini göreceksiniz. Bu konuyla ilgili olarak SCD modülünün Description bölümünde şöyle (aslında doğru) bir açıklama göreceksiniz.

– As this Knowledge Module is dedicated to Datawarehouse Projects (where data should not be removed), when using it with a journalized Source Datastore, it is not possible to synchronize deletions. Therefore, data should be manually filtered to exclude any source delete events (add a filter on JRN_FLAG = ‘I’).

Ama bazı durumlarda kaynakta meydana gelen fiziksel silme işlemini hedefte mantıksal olarak görmemiz gerekebilir.  Talep değişken olmakla beraber en azından kaydın ömrünün tamamlandığını belirtmek üzere ENDING TIMESTAMP ve artık aktif olmadığını işaret etmek üzere de CURRENT RECORD FLAG kolonlarının update edilmesi gerekebilir. (ki bu yazının sebebi değerli bir müşterimizden bu yönde gelen bir taleptir…) Örneğin;

Hedef tablo – Kaynak tabloda fiziksel silme yapılmadan önce

Id                Ad              Soyad                Starting_TS      Ending_TS            CR_Flag

1                 ECE            AYHAN               01.06.2012        01.01.2400            1

Hedef Tablo – Kaynak tabloda fiziksel silme yapıldıktan sonra

Id                Ad              Soyad                Starting_TS      Ending_TS            CR_Flag

1                 ECE            AYHAN               01.06.2012       26.09.2013            0

Bu durumda ne yapmam gerektiğini öğrenmek üzere yaptığım bir internet araması sonucunda da özel olarak bu durumda ne yapılması gerektiği konusunda bir içerik bulamadım.  Daha sonra KM kodlarını incelediğimde aslında basit bir çözümün olduğunu gördüm. (İnternette çözüm bulamama nedenim bu olabilir 🙂 )

Çözüm :

IKM Oracle SCD modülünde “Historize old rows” adımını inceleyince bu modülün yapmak istediğimiz ENDING TIMESTAMP ve CURRENT RECORD FLAG kolonlarını zaten update ettiğini ancak mantık gereği silinen kayıtları devre dışı bırakmak için iki yerde IND_UPDATE = ‘I’ (sadece yeni eklenen ve update edilen satırlar, evet updateler de Journal tablosuna “I” flagiyle gelir) şartını kullandığını görebilirsiniz. Tek yapmamız gereken silinen kayıtları da Historize adımına dahil etmek, bunun için de aşağıdaki değişikliği yapmamız yeterli.

IKM Oracle Slowly Cahnging Dimension modülü – “312 Historize Old Rows” betiği Orjinal durumu : 

Historize

İhtiyacımıza göre modifiye edilmiş hali : 

Historize_mod

Bu işlem update edilmiş satırların eski sürümünü historize ederken silinen satırların karşılıklarının da Current Record Flag = 0 ve Ending Timestamp =(TXN_TIME ya da SYSDATE) alanlarını  günceller. Bu çözüm SCD için hazırlanmıştır benzer yöntemle Incremental Update modülünü de düzenleyebilirsiniz. İyi çalışmalar.

Merhaba, Oracle ile çalışan herkesin şimdiye kadar kullanmadıysa bile mutlaka duyduğu analitik fonksiyonlardan olan LEAD() ve LAG() fonksiyonlarının kullanımını inceleyeceğiz.

Genel olarak tanımlamak gerekirse;

LEAD() : Belirli bir sıra halinde gelen veri setimizde ilgili satırın herhangi bir kolonunun bir sonraki satırda aldığı değeri verir. (Offset değerini değiştirerek 2 veya daha sonraki kolon değerine de ulaşabiliriz.) 

Syntax : LEAD ( DEGERI_ISTENEN_KOLON, [offset]) OVER ( ORDER BY SIRALAMA_KOLONU)

LAG() : LEAD() fonksiyonuyla aynı işi önceki satırlar için yapar.

Syntax : LAG ( DEGERI_ISTENEN_KOLON, [offset]) OVER ( ORDER BY SIRALAMA_KOLONU)

Bir örnek üzerinden ilerleyerek fonksiyonların amacını ve kullanımını daha kolay inceleyebiliriz. Ay bazında ortalama sıcaklıkların saklandığı bir tablomuz (T_ORTALAMA_SICAKLIK) olsun.

CREATE TABLE T_ORTALAMA_SICAKLIK
(ID NUMBER,
AY NUMBER,
AY_STR VARCHAR2(20),
ORT_SICAKLIK NUMBER);

ve bu tabloda test yapabilmemiz için mantıklı değerler içeren satırlarımız,

INSERT INTO T_ORTALAMA_SICAKLIK VALUES (1, 201201, ‘OCAK 2012’, 6.5);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (2, 201202, ‘ŞUBAT 2012’, 6.5);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (3, 201203, ‘MART 2012’, 8.3);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (4, 201204, ‘NİSAN 2012’, 12.7);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (5, 201205, ‘MAYIS 2012’, 17.5);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (6, 201206, ‘HAZİRAN 2012’, 22.1);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (7, 201207, ‘TEMMUZ 2012’, 24.4);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (8, 201208, ‘AĞUSTOS 2012’, 24.2);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (9, 201209, ‘EYLÜL 2012’, 20.9);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (10, 201210, ‘EKİM 2012’, 16.4);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (11, 201211, ‘KASIM 2012’, 12.2);
INSERT INTO T_ORTALAMA_SICAKLIK VALUES (12, 201212, ‘ARALIK 2012’, 8.7);

kayıtları da ekledikten sonra ilk anda tabloyu sorguladığımızda aşağıdaki gibi bir görüntümüz olacaktır,

ll_ilks

Aylar arasında nasıl bir sıcaklık değişikliği olduğu bilgisine ulaşmak için her ayın ORT_SICAKLIK kolonunun yanına önceki ve sonraki ay ortalamalarını eklemek istediğimiz zaman LEAD(), LAG() fonksiyonlarına ihtiyaç duyuyor olacağız.

Bu örneğimizde mantıklı sıralama AY kolonu üzerinden, öncekiyle sonraki satırlardan getirmek istediğimiz değerler ise ORT_SICAKLIK kolonlarındaki değerler olacak.  (önceki ay bilgisi) LAG() bizim örneğimizde şu şekilde kullanılmalıdır : LAG(ORT_SICAKLIK, 1) OVER(ORDER BY AY), (sonraki ay) LEAD() fonksiyonu ise LEAD(ORT_SICAKLIK, 1) OVER(ORDER BY AY)  şeklinde yer alacaktır. Sorgunun tamamı;

SELECT
AY_STR,
LAG (ORT_SICAKLIK, 1) OVER (ORDER BY AY) ONCEKI_AY_ORT,
ORT_SICAKLIK,
LEAD (ORT_SICAKLIK, 1) OVER (ORDER BY AY) SONRAKI_AY_ORT
FROM T_ORTALAMA_SICAKLIK;

bu sorgudan elde edeceğimiz sonuç ise aşağıdaki gibi olacaktır.

ll_funcs

Ay özelinde inceleyecek olursak MAYIS 2012 ortalama sıcaklığının(ORT_SICAKLIK) 17.5 iken aynı satırda önceki ay ortalamasının (ONCEKI_AY_ORT) 12.7, sonraki ay ortalamasının (SONRAKI_AY_ORT) 22.1 olduğunu görebiliyor olacağız. Böylelikle aynı satırda yer alan bu üç kolon üzerinde işlemler yapıp yüzde olarak değişiklik vb. gibi hesaplamalar yapmak da mümkün olacaktır. iyi çalışmalar.

Merhaba, LinkedIn üzerinde bir arkadaşımın gönderdiği soru üzerine bu gönderiyi hazırlamaya karar verdim.

Soru özetle, her iki modülü kullanarak da aktarım yapabildiği ancak çok büyük tabloların aktarımında performans açısından hangisinin daha performanslı olacağı yönündeydi.

İlk olarak; eğer hedef veritabanınız Oracle ise kesinlikle LKM SQL to Oracle’ı kullanmanız gerektiğini belirttikten sonra nedenlerini sıralayalım.

  • LKM Sql to Oracle, önceki çalışmasından kalan Work Table’a drop işlemi yaparken Purge kullanır, LKM SQL to SQL kullanmaz. (Purge kullanılmadığı durumda tablo Recycle Bin’e taşınıp bir süre daha yer kaplamaya devam eder)
  • LKM S2O modülünde /*+NOLOGGING PARALLEL */ gibi tablo hintleri kullanabiliyorken LKM S2S’de böyle bir seçenek bulunmuyorLKMs2o
  • LKM S2O modülü Work Table’a yapılan INSERT işleminde default olarak /*+ APPEND NOLOGGING*/ hinti kullanırken LKM S2S modülünde bu hintler kullanılmaz. Dolayısıyla Load işlemi S2O modülünde çok daha hızlı olacaktır.
  • LKM S2O oluşturulan Work Table’a gelecek sorguların çok daha hızlı çalışabilmesi için tabloya index ekleyip istatistiğini toplarken LKM S2S bu işlemi yapmaz.

Eğer ki veritabanımız Oracle ise ve bu iki modül arasında seçim yapacaksak kesinlikle  LKM Sql to Oracle modülünü kullanmamız gerektiğini bir kez daha belirterek bu konuyu sonlardırabiliriz. İyi çalışmalar

OLTP sistemlerde update gören bir satırın önceki haline ulaşmanın çok zor olduğu açık. Peki bir önceki hali de değil istediğim bir anda o satırın durumu neydi desem, iş iyice içinden çıkılmaz bir hal alıyor gibi. Pek tabii OLTP’de de bunu sağlayacak bir altyapıyı kurmak mümkün ama bu OLTP için hem ekstra yük(her açıdan) hem zahmetli hem de biraz gereksiz bir iş.  Onun için tam da bu noktada devreye veri ambarı ve kaçınılmaz olarak da Slowly Changing Dimension metodu giriyor.

Bir tabloyu SCD olarak saklamak için birden fazla yol, bu yolları kullanmak için de PL/SQL, T-SQL dahil kullanabileceğiniz birden fazla araç var. Biz burada tahmin edebileceğiniz gibi bu işi ODI üzerinde nasıl yapabileceğimize yoğunlaşıp bir örnekle de daha anlaşılır olmasını sağlamaya çalışacağız.

Elimizde personel bilgilerinin saklandığı bir tablo olduğunu düşünelim;

CREATE TABLE OLTP.PERSONEL
(
PERSONEL_ID NUMBER NOT NULL PRIMARY KEY,
AD VARCHAR2(50 BYTE),
SOYAD VARCHAR2(50 BYTE),
BIRIM_ID NUMBER
);

personel bilgileri özellikle birim, ünvan gibi bilgileri sık sık değişebilecek verilerdir ve bir personelin şu andan 4 ay önce veya 2 yıl önce hangi birimde olduğu bilgisi önemli bir bilgidir. Bu bilgiye ulaşmak için hedef tablomuzda ekstra bir kaç kolona daha ihtiyaç duyuyoruz.

CREATE TABLE KDS.PERSONEL_SCD
(
PERSONEL_SK NUMBER,
PERSONEL_ID NUMBER,
AD VARCHAR2(50 BYTE),
SOYAD VARCHAR2(50 BYTE),
BIRIM_ID NUMBER,
BAS_TAR DATE,
BIT_TAR DATE
);

Hedef tabloya eklediğimiz BAS_TAR ve BIT_TAR kolonlarımızın eklenme sebebine değinelim;

Örneğin A personeli 2005 yılından 2009 yılına kadar Yazılım birimindeydi, 2009’dan beri ise AR-GE biriminde. 

OLTP tarafında 01.01.2009 yılına kadar;

Personel               Birim

A                              Yazılım

2009 yılından sonra ise;

Personel               Birim

A                              AR-GE

şeklinde kayıt görürsünüz.

DW tarafında ise 01.01.2009 tarihine kadar;

Personel               Birim                      BAS_TAR                           BIT_TAR

A                              Yazılım                  01.01.2005                       01.01.2400

01.01.2009 tarihinden sonra ise

Personel               Birim                      BAS_TAR                           BIT_TAR

A                              Yazılım                  01.01.2005                       01.01.2009

A                              AR-GE                    01.01.2009                       01.01.2400

şeklinde görürsünüz. Dolayısıyla DW tarafındaki tabloya tarih parametresiyle gittiğiniz takdirde personelin hangi tarihte nerede olduğu bilgisine ulaşmanız artık çok kolay. Ve bu kolaylğı bize sağlayan BAS_TAR ve BIT_TAR kolonları. (kolon isimleri opsiyonel :))

Yukarıdaki örnekte sizin de şimdiye kadar farketmiş olacağınız gibi artık PERSONEL_ID kolonunun uniqueliğinden bahsedemeyiz, dolayısıyla yeni bir unique kolona ihtiyacımız var(Surrogate Key) ve bu da PERSONEL_SK.

Hem kaynak hem de hedef tablonun oluşturulup ODI modeline alındığını varsayarak SCD interface’ini hazırlamaya başlayabiliriz.

İlk olarak hedef tablo PERSONEL_SCD’yi modelden açıp kolon editörüne geçip Description kısmından Slowly Changing Dimension Behavior değerlerini set etmemiz gerekiyor.

col_edit

Bizim Örneğimizde; PERSONEL_SK = Surrogate Key, PERSONEL_ID = Natural Key, AD, SOYAD, BIRIM_ID = Add Row On Change, BAS_TAR = Starting Timestamp, BIT_TAR = Ending Timestamp değerlerini almalıdır.

Yeni interface ekranı açıp tanımlama kısmını tamaladıktan sonra Mapping sekmesine geçip tablolarımızı ilgili yerlere sürükleyebiliriz. eğer kolon isimlerini değiştirmediysek yeni eklediğimiz kolonlar hariç diğerlerini ODI otomatik olarak eşleştirecektir.

scd_int1

Surrogate Key alanı değerini bir sequence’ten almalıdır. Kullanacağımız sequence’i ODI üzerinde tanımladıktan sonra Surrogate Key alanının mappingine SEQUENCE_ADI_NEXTVAL yazabilirsiniz. Yine mapping kısmına BAS_TAR için SYSDATE, BIT_TAR için çok ileri bir tarih verelim. Mappingimizin son hali aşağıdakine benzer olmalıdır.

int_mapson

Mapping aşamasını tamamladıktan sonra Flow sekmesine geçip kullanacağımız SCD Knowledge Module’ü seçebiliriz. Veritabanımızın oracle olduğunu varsayarak  IKM Oracle Slowly Changing Dimension‘u seçtim. (Yoksa import edebilirsiniz)

scd_km

Modülü seçip (basit kullanım için) Flow Control  seçeneğini false değerine set ettikten sonra interfac’i kaydedebiliriz.

Interface’i ilk çalıştırdığınızda tüm kayıtların o anki değerini o ank tarihle SCD tablosuna atar. Test etmek için kendi örneğimizde kaynak tabloya iki kayıt ekleyip interface’i çalıştırdıktan sonra hedef tabloyu kontrol edelim.

INSERT INTO OLTP.PERSONEL (PERSONEL_ID, AD, SOYAD, BIRIM_ID)
VALUES (157, ‘SUNA’, ‘SEYHAN’, 1);

INSERT INTO OLTP.PERSONEL (PERSONEL_ID, AD, SOYAD, BIRIM_ID)
VALUES (441, ‘BÜLENT’, ‘ŞEN’, 1);

Interface ilk kez çalıştıktan sonra hedef tablo (KDS.PERSONEL_SCD);

ilkak_sonuc

kaynak tablodaki kayıtlardan birinin üzerinde bir güncelleme yapıp interfacei tekrar çalıştırdığımız zaman neler olduğunu görelim.

UPDATE OLTP.PERSONEL SET BIRIM_ID = 45 WHERE PERSONEL_ID = 147;

Update işlemi ve devamında interface’i tekrar çalıştırma sonucu oluşan hedef tablo;

farkak_sonuc

Görülebileceği gibi update gören satırı çokladı ve kaydın hem eski hali hem de yeni hali saklanıyor. Örneğin ID değeri 157 olan personelin hangi tarihte hangi birimde olduğu bilgisine tarih parametresiyle ulaşabiliriz. İyi çalışmalar.

Veri ambarına aktarım yaparken her seferinde kaynak tablodaki tüm veriyi hedefle karşılaştırmak yerine ilk aktarımdan sonra sadece değişen kayıtları karşılaştırıp çok daha küçük bir veri seti üzerinde işlem yaparak aktarım işlemini tamamlayabiliriz. Değişen kayıtların tespit edilmesi konusunda da ODI’ın bize sunduğu Journalizing özelliğinden yararlanabiliriz. Bu yazımızda temel manada Değişen verileri yakalama (CDC) ve hedef tabloyla birleştirme (MERGE) işlemini ODI üzerinde nasıl yapacağımızı ele alacağız.

Öncelikle anlatımda bize yardımcı olacak tabloları oluşturalım;

Kaynak Tablo :

CREATE TABLE CDC_SOURCE
(
KISI_ID NUMBER NOT NULL PRIMARY KEY,
AD VARCHAR2(50 BYTE),
SOYAD VARCHAR2(50 BYTE)
);

* Kaynak tabloda primary key tanımlanmış olması gerekiyor.

Hedef Tablo :

CREATE TABLE CDC_TARGET
(
KISI_ID NUMBER,
AD VARCHAR2(50 BYTE),
SOYAD VARCHAR2(50 BYTE)
);

İlk aktarım vs. yoluyla ilk anda ikisinin de eşitlenmiş olduğunu varsayıyorum. Bizim örneğimizde ikisi de boş olduğu için eşit zaten ^^

  • Reverse Engineer araclığıyla tablolarımızı modele ekliyoruz.

rev

Bu adımdan sonra source ve target tabloları kendi modelleri altında görebiliyor olmamız gerekiyor.  cdc_model

  • Modelde kaynak tablonun üzerine sağ tıklayıp Change Data Capture menüsünün altından Add to CDC‘yi seçiyoruz.add_to_cdc

Bu aşamada gelecek doğrulama sorusunu evet diyerek geçtikten sonra kaynak tablo üzerinde CDC’ye dahil olduğunu belirten sarı bir saat simgesi cdc_added görüyorsanız şu ana kadar her şey yolunda demektir.

  • Şu ana kadar her şey yolundaysa yine Change Data Capture menüsü altından Start Journal diyebiliriz. start_journal

Subscriber seçiminde SUNOPSIS seçip devam edince kaynak tablo üzerindeki saat simgesinin renginin sarıdan yeşile dönmüş olması gerekiyor. journalized

An itibariyle ODI Journalize işlemine başlamıştır. Örnek bir kaç kayıt ekleyerek kontrol edelim.

INSERT INTO CDC_SOURCE (KISI_ID, AD, SOYAD) VALUES (1, ‘METİN’, ‘TEKİN’);
INSERT INTO CDC_SOURCE (KISI_ID, AD, SOYAD) VALUES (2, ‘ALİ’, ‘GÜLTİKEN’);

sqlplus’ta ilgili scriptleri çalıştırıp, ODI’da kaynak tablo üzerinde Journal Data seçeneğini seçersek işlem gören kayıtları yakaladığını görebiliyor olacağız.

Journal Data

*** Şu an sadece değişen kayıtları yakalamış olduk. bunları hedef tabloya uygulamak için Interface hazırlamamız gerekiyor.

Interface adımında özellikle dikkat etmemiz gereken nokta 2 nokta var, bunlardan birincisi Mapping sekmesinde kaynak tablonun Property Inspector ekranında Journalized Data only seçeneğini işaretlemiş olmamız gerektiği,

int_mapping

Bir diğeri ise kullanacağımız JKM ve IKM modüllerini ihtiyacımıza uygun seçmemiz. Bu örnekte JKM olarak JKM Oracle Simple, IKM olarak ise IKM Oracle Incremental Update (MERGE) modülünü kullandım. Siz ihtiyacınıza bağlı olarak SCD modüllerinden birini veya daha başka bir modül kullanabilirsiniz.

int_flow

Hazırladığımız interface’i çalıştırdıktan sonra hedef tabloyu kontrol edersek yapılan değişikliklerin hedefe uygulandığını görebiliyor olacağız.

trg_ilk

* Bu aşamada ODI Journal tablosunu sıfırlar.  

Bir test daha yaparak konuyu tamamlayalım; Bir kayıt ekleyip, var  olan bir kaydı da güncelledikten sonra ne olacağını görelim.

INSERT INTO CDC_SOURCE (KISI_ID, AD, SOYAD) VALUES (3, ‘FEYYAZ’, ‘UÇAR’);
UPDATE CDC_SOURCE SET SOYAD = ‘SARIFIRTINA’ WHERE KISI_ID = 1;

Journal Data;

Journal Data2

Interface’i tekrar çalıştırdıktan sonra hedef tablo (CDC_TARGET) ;

trg_2

Interface’in senaryosunu oluşturup zamanlarsanız belirteceğiniz periyodda hedef tablonuzdaki verilerin kaynak tabloya eşitlenmesini sağlayabilirsiniz. İyi çalışmalar.

Aşağıdaki gibi bir insert cümlemizin olduğunu ve bu işlemi ODI Interface’ine taşımak istediğimizi  varsayalım,

INSERT INTO PERSONEL_SIRALI
(
SICIL_NO,
AD,
SOYAD,
UNVAN,
SIRA
)
SELECT
SICIL_NO,
AD,
SOYAD,
UNVAN,
ROW_NUMBER() OVER (PARTITION BY P.SICIL_NO ORDER BY P.GUNCELLEMETARIHI DESC) SIRA
FROM PERSONEL_UNVAN P

 

Bu gibi durumlarda ODI mapping aşamasında analitik fonksiyonların yazımı biraz değişiyor.

SIRA kolonunun karşılığına <?out.print(“ROW_NUMBER”);?>() OVER (PARTITION BY P.SICIL_NO ORDER BY P.GUNCELLEMETARIHI DESC)

yazıldığı takdirde istenen sonuç elde edilebilecektir. (PERSONEL_UNVAN tablosunun aliasının P olarak tanımlandığı varsayılmıştır.)

analitik_fonksiyon

 

Daha sonra bu olayı SCHEMA TRIGGERLARI adı altında daha detaylı inceleyebiliriz ama şimdi birebir çözüm olduğu bir olaydan bahsetmek istiyorum. Şu anda üzerinde çalıştığımız projede ODS olarak kullanmak üzere GoldenGate ile veritabanının birebir kopyasını oluşturuyoruz. Operasyonel veritabanından yapısal olarak en önemli farkı her tablonun ekstra olarak ilgili satırın son gördüğü işlem tipini(INSERT, UPDATE) ve işlem zamanını saklayan iki kolona sahip olması.

Sorun : Goldengate parametrelerinde hedefte bu iki ekstra kolonun da bulunduğu şekilde tanım yapılmış olmasına rağmen kaynak veritabanındaki bir tablo DROP, CREATE işlemine uğrayınca veya yeni bir tablo CREATE edilince hedefte oluşan tabloda bu iki ekstra kolon oluşmuyor ve GOLDENGATE mapping yüzünden hata veriyor. Bir süre bu sorunu her bu tip değişiklik olduğunda elle ilgili alanları yaratarak aştık ama nereye kadar, bu arada goldengate’in durduğunu da hesaba katarsak bize daha kullanışlı bir çözüm gerekti.

Çözüm :  Şema bazında yaratılacak bir AFTER CREATE ON SCHEMA triggerla çalışan her ddl den sonra eğer bu bir CREATE işlemiyse triggera düşüyor ve biz de trigger içinde  ora_dict_obj_type değerine bakarak bunun bir table creati olup olmadığına bakıyoruz ve eğer create table işlemiyse ilgili alanları  ora_dict_obj_name’den ismini aldığımız tabloya ekliyoruz.

CREATE OR REPLACE TRIGGER ODS.DEF_OT_TS_EKLE
AFTER CREATE ON SCHEMA
DECLARE
l_sysevent varchar2(25);
l_Obje_Name varchar2(30);
l_Obje_Type varchar2(30);
OTekleSQL varchar2(400);
TSekleSQL varchar2(400);
begin
select ora_sysevent into l_sysevent from dual;

select ora_sysevent, ora_dict_obj_name, ora_dict_obj_type into l_sysevent, l_Obje_Name, l_Obje_Type from dual;

if ( l_Obje_Type in (‘TABLE’) )
then
TSekleSQL := ‘ALTER TABLE ‘||l_Obje_Name||’ ADD TS TIMESTAMP(6)’;
OTekleSQL := ‘ALTER TABLE ‘||l_Obje_Name||’ ADD OT VARCHAR2(20 BYTE)’;
EXECUTE IMMEDIATE TSekleSQL;
EXECUTE IMMEDIATE OTekleSQL;
end if;
end;
/

%d blogcu bunu beğendi: