18 Şubat 2023 • 30 dakikalık okuma
PostgreSQL trigger, cursor, transaction ve exception tanımlamak için terminal ekranından postgres veritabanına bağlandıktan sonra;
Tetikleyici, (ing.: Trigger) belirli veritabanı işlemlerinden öncesinde, sırasında ya da sonrasında çalışan fonksiyondur. Trigger, insert, update, delete işlemleri için tanımlanır. Trigger ne zaman çalışacağı before, after, instead of değerleri ile belirtilir. İşlemden etkilenen her kayıt için trigger çalıştırılmak isteniyor ise for each row, bir defa çalıştırılmak isteniyor ise for each statement olarak tanımlanır. Trigger içinde eklenen, güncellenen ve silenen değerlere NEW.kolon_ismi veya OLD.kolon_ismi ile erişilebilir.
Triggerın oluşturmak için;
create [ or replace ] [ constraint ] trigger name { before | after | instead of } { event [ or ... ] }
on table_name
[ from referenced_table_name ]
[ not deferrable | [ deferrable ] [ initially immediate | initially deferred ] ]
[ referencing { { old | new } table [ as ] transition_relation_name } [ ... ] ]
[ for [ each ] { row | statement } ]
[ when ( condition ) ]
execute { function | procedure } function_name ( arguments )
Triggerın çalıştıracağı fonksiyonu tanımlamak;
create function insertCountryForBackup() returns trigger as $func$
begin
insert into country_backup (id, code, title, createddate) values (new.id, new.code, new.title, new.createdDate);
return new;
end;
$func$
language plpgsql;
country tablosunda insert komutundan sonra çalışacak trigger tanımlamak;
create trigger backupCountry after insert on country
for each row execute function insertCountryForBackup();
Trigger çalıştırmak için;
insert into country (code, title, createddate) values ('UZ', 'Özbekistan', '2023-02-04');
Triggerın çalıştıracağı fonksiyonu tanımlamak;
create function logDeleteCountry() returns trigger as $func$
begin
insert into country_log (countryID, countryTitle, command, username, commandDate) values (old.id, old.title, 'Delete', current_user, now());
return new;
end;
$func$
language plpgsql;
country tablosunda delete komutundan sonra çalışacak trigger tanımlamak;
create trigger logCountryDelete after delete on country
for each row execute function logDeleteCountry();
Trigger tablonun kolonu bazında da tanımlanabilir;
employee tablosunda update komutundan önce salary kolonu güncellendiğinde çalışacak trigger tanımlamak;
create trigger check_salary_update
before update of salary on employee
for each row
execute function logSalaryUpdate();
Oluşturulan mevcut trigger tanımlarını görmek için;
select tgname from pg_trigger;
alter table country
disable trigger backupCountry;
alter table country
enable trigger backupCountry;
Mevcut trigger tanımlarını silmek için;
drop trigger backupCountry
İmleç, (ing.: Cursor) veritabanı sorgu sonucunda döndürülen kayıtlarda satır satır işlem yapılmasını sağlar;
create or replace function fn_test_cursor() returns text
language plpgsql as $func$
declare cursorSetEmail cursor for select id, firstName, lastName from employee where email is null;
currentID int;
currentFirstName varchar(100);
currentLastName varchar(100);
name varchar(100);
lastname varchar(100);
emailAddress varchar(500);
begin
open cursorSetEmail;
loop
fetch cursorSetEmail into currentID, currentFirstName, currentLastName;
exit when not found;
name := lower(replace(currentFirstName, ' ', '.'));
lastname := lower(replace(currentLastName, ' ', '.'));
emailAddress := concat(name, '.', lastName, '@amazing.com');
raise notice '% % % : %', currentID, currentFirstName, currentLastName, emailAddress;
update employee set email = emailAddress where id = currentID;
end loop;
close cursorSetEmail;
return 'Done';
end
$func$;
Cursor çalıştırmak için ilgili fonksiyon çağırılır;
select * from fn_test_cursor();
İstisna, (ing.: Exception) kod çalışırken oluşan hatalardır. Tanımlı istisnalar dışında, istenen durum için kullanıcı tanımlı özel istisnalar da tanımlanabilir;
do
$func$
declare
username varchar := 'aydan';
begin
raise exception 'Kullanıcı adı zaten mevcut: "%"', username
using hint = 'Farklı bir kullanıcı adı giriniz.';
end
$func$;
Bir hata meydana geldiğinde tüm istisnaları yakalamak için;
create or replace function getPersonTableCount()
returns int
as
$func$
declare personCount integer;
begin
begin
select count(*) into personCount from persoooonnnn;
return personCount;
exception
when others then
return -1;
end;
end;
$func$
language plpgsql;
Bir hata meydana geldiğinde belirli istisnaları yakalamak için;
exception
when no_data_found then
return -1;
when zero_divide then
return -2;
when too_many_rows then
return 5000;
İşlem, (ing.: Transaction) birden fazla işlemi tek işlem gibi çalıştıran ve sorun olduğunda tüm işlemleri geri almayı sağlayan yapıdır.
Transaction tanımlar ve işlemi onaylar;
begin transaction;
update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;
commit transaction;
Transaction tanımlar ve işlemi geri alır;
begin transaction;
update account set balance = balance - 750 where id = 1;
update account set balance = balance + 750 where id = 2;
rollback transaction;