Merhaba
Elimde uygulama için kullandığım bir veri tabanı var ve içinde bir sürü tablo var. Bu veri tabanının birden fazla farklı uygulama için kullanımları var*fakat yapı olarak*birebir aynı veri tabanı.
Ben bu tablolarda silme veya değişiklik*yapıldığında bir kopyasını log olarak tutmak istiyorum.
Bende şöyle bir yol izlemeyi planladım. Log için bir tane veri tabanı oluşturup. Daha sonra bunun içinde PostgreSQL in güzel bir özelliği olan schema ile her farklı uygulama için bir schema açıp bu veri tabanı içinde logları toplu halde tutmak istiyorum.
Log işlemini*aynı veri tabanı içinde olursa aşağıdaki kod ile*sorunsuz işlemi yapabiliyorum. Hangi tablo olursa olsun direkt olarak*OLD*içindeki tablo verisini direkt olarak tablo adı bilgisi ile*INSERT*ediyor.
EXECUTE format('INSERT INTO %I.%I VALUES ($1.*)', (SELECT current_database()), TG_TABLE_NAME)
USING OLD;
RETURN OLD;
Farklı veritabanı*içinde tutmak istediğimde ise*bir yerde takıldım ve buna ek olarak farklı görüş ve fikirlere de açığım. Her tablo için farklı trigger ler yazabilirim fakat bu çok fazla amatör ve zaman gerektiren bir işlem daha sonra da bir güncelleme yapılmak istenirse buda çok fazla zaman alır.
_old_val := (SELECT array[OLD.*]);* --OLD içindeki*bilgiyi bir şekilde parse edip 'ELMA', 'ARMUT', 'PATATES' gibi ayırmam gerekiyor
_sql := (SELECT format('INSERT INTO %I.%I VALUES (%L, %L, %L)', _database, TG_TABLE_NAME, _username, _ip, _old_val));
PERFORM dblink('host=localhost user=postgres password=123 dbname=ths_erp_log port=5432', '' ||*_sql);
Yukarıdaki _old_var değişkenin sonucu aşağıdaki gibi*geliyor. Arada null olan bilgiler var. Bunlarda direkt virgül var hiç bir şey yazmıyor.
ERROR: SQL=INSERT INTO ths_erp2017.cins_ozelligi VALUES ('THS_ADMIN', '127.0.0.1/32', E'{"(13,t,1,PANOFONK,\\"TABLO FONKSİYON\\",ANAKART,HABERLEŞME,TAHRİK,\\"BASİT KUMANDA\\",\\"AŞAÐI TOPLAMA\\",\\"ÇİFT DÜÐME\\",,,,\\"ASANSÖR STANDART\\",,SERİ,f)"}')I'.
Asıl olaması gereken durum ise
INSERT INTO ths_erp2017.cins_ozelligi VALUES ('THS_ADMIN', '127.0.0.1/32', 13,t,1,'PANOFONK', 'TABLO FONKSİYON', 'ANAKART', 'HABERLEŞME', 'TAHRİK', 'BASİT KUMANDA', 'AŞAÐI TOPLAMA', 'ÇİFT DÜÐME', NULL, NULL, NULL, 'STANDART', NULL, 'SERİ', f);OLD içindeki bilgiyi birşekilde*parse edebilirsem hiç bir derdim kalmayacak sorunsuz olarak farklı bir veri tabanı içinde herhangi bir tablo için shadow copy işlemini yapmış olacağım.
OLD yerine trigger içinde işlem yapılan tablo belli o tablo içeriğini de alabilirim.
*
EXECUTE format('SELECT * FROM %I WHERE %s=%s', TG_TABLE_NAME, TG_TABLE_NAME || '.id',*OLD.id)
*Fakat asıl veriyi işleyip tırnakla ayrılmış*text gibi dönüştürmem ve _old_val içinde bu bilgiyi göndermem gerekiyor.
Biraz karışık oldu galiba
Elimde uygulama için kullandığım bir veri tabanı var ve içinde bir sürü tablo var. Bu veri tabanının birden fazla farklı uygulama için kullanımları var*fakat yapı olarak*birebir aynı veri tabanı.
Ben bu tablolarda silme veya değişiklik*yapıldığında bir kopyasını log olarak tutmak istiyorum.
Bende şöyle bir yol izlemeyi planladım. Log için bir tane veri tabanı oluşturup. Daha sonra bunun içinde PostgreSQL in güzel bir özelliği olan schema ile her farklı uygulama için bir schema açıp bu veri tabanı içinde logları toplu halde tutmak istiyorum.
Log işlemini*aynı veri tabanı içinde olursa aşağıdaki kod ile*sorunsuz işlemi yapabiliyorum. Hangi tablo olursa olsun direkt olarak*OLD*içindeki tablo verisini direkt olarak tablo adı bilgisi ile*INSERT*ediyor.
EXECUTE format('INSERT INTO %I.%I VALUES ($1.*)', (SELECT current_database()), TG_TABLE_NAME)
USING OLD;
RETURN OLD;
Farklı veritabanı*içinde tutmak istediğimde ise*bir yerde takıldım ve buna ek olarak farklı görüş ve fikirlere de açığım. Her tablo için farklı trigger ler yazabilirim fakat bu çok fazla amatör ve zaman gerektiren bir işlem daha sonra da bir güncelleme yapılmak istenirse buda çok fazla zaman alır.
_old_val := (SELECT array[OLD.*]);* --OLD içindeki*bilgiyi bir şekilde parse edip 'ELMA', 'ARMUT', 'PATATES' gibi ayırmam gerekiyor
_sql := (SELECT format('INSERT INTO %I.%I VALUES (%L, %L, %L)', _database, TG_TABLE_NAME, _username, _ip, _old_val));
PERFORM dblink('host=localhost user=postgres password=123 dbname=ths_erp_log port=5432', '' ||*_sql);
Yukarıdaki _old_var değişkenin sonucu aşağıdaki gibi*geliyor. Arada null olan bilgiler var. Bunlarda direkt virgül var hiç bir şey yazmıyor.
ERROR: SQL=INSERT INTO ths_erp2017.cins_ozelligi VALUES ('THS_ADMIN', '127.0.0.1/32', E'{"(13,t,1,PANOFONK,\\"TABLO FONKSİYON\\",ANAKART,HABERLEŞME,TAHRİK,\\"BASİT KUMANDA\\",\\"AŞAÐI TOPLAMA\\",\\"ÇİFT DÜÐME\\",,,,\\"ASANSÖR STANDART\\",,SERİ,f)"}')I'.
Asıl olaması gereken durum ise
INSERT INTO ths_erp2017.cins_ozelligi VALUES ('THS_ADMIN', '127.0.0.1/32', 13,t,1,'PANOFONK', 'TABLO FONKSİYON', 'ANAKART', 'HABERLEŞME', 'TAHRİK', 'BASİT KUMANDA', 'AŞAÐI TOPLAMA', 'ÇİFT DÜÐME', NULL, NULL, NULL, 'STANDART', NULL, 'SERİ', f);OLD içindeki bilgiyi birşekilde*parse edebilirsem hiç bir derdim kalmayacak sorunsuz olarak farklı bir veri tabanı içinde herhangi bir tablo için shadow copy işlemini yapmış olacağım.
OLD yerine trigger içinde işlem yapılan tablo belli o tablo içeriğini de alabilirim.
*
EXECUTE format('SELECT * FROM %I WHERE %s=%s', TG_TABLE_NAME, TG_TABLE_NAME || '.id',*OLD.id)
*Fakat asıl veriyi işleyip tırnakla ayrılmış*text gibi dönüştürmem ve _old_val içinde bu bilgiyi göndermem gerekiyor.
Biraz karışık oldu galiba