After Insert trigger ne radi prilikom inserta kroz SSIS paket

Objavljeno: 19-02-2015 | Autor: Miloš Milenković | Kategorija: SSIS

2

Često se javlja potreba da se prilikom upisivanja podataka u neku tabelu o tome obaveste određeni korisnici ili da se to negde zabeleži, zajedno sa vremenom kad je podatak upisan i korisnikom koji je izvršio upisivanje. Najpraktičniji način da se ovo uradi je upotreba trigera.

Za ovu priliku, kreiraćemo tabelu u koju će biti upisani pomenuti podaci prilkom svakog dodavanja novog reda u tabelu CrtaniFilmovi u našoj bazi SQL_KEFALO:

CREATE TABLE log_insert
(id int IDENTITY,
CrtacID int,
Naziv nvarchar(50),
Korisnik nvarchar(50),
Datum datetime DEFAULT(GETDATE()));

Zatim na tabeli CrtaniFilmovi kreiramo After Insert triger koji će u kreiranu tablu logovati crtani film koji je dodat u tabelu, kao i naziv korisnika koji je dodao taj novi red u tabelu i vreme dodavanja:

CREATE TRIGGER trg_LogInsert ON CrtaniFilmovi
AFTER INSERT
AS
BEGIN
	INSERT INTO log_insert (CrtacID, Naziv, Korisnik)
	SELECT CrtacId, Naziv, SUSER_SNAME() 
        FROM inserted;
END

Sada možemo da probamo da li kreirani triger radi tako što ćemo dodati novi red u tabelu CrtaniFilmovi, a onda proveriti tabelu log_insert.

INSERT INTO CrtaniFilmovi(CrtacID, Naziv, Opis, DatumIzmene)
VALUES(5, 'Mornar Popaj', 'Mornar Popaj je crtani junak iz istoimenog crtanog filma i stripa. Prvi put se pojavio u novinskom stripu „King fičers“ 17. januara 1929. godine, tako što ga je američki crtač stripova Elsi Segar uveo kao novi lik u svoj već deceniju star strip „Timbl teatar“.', GETDATE());

SELECT * FROM log_insert;

Nakon izvršavanja drugog upita, vidimo da se u tabeli log_insert nalazi jedan red:

što pokazuje da triger radi upravo ono što smo očekivali.

Međutim, ako pokušamo da ulogujemo dodavanje novog reda u slučaju kada se podaci u tabelu dodaju preko SSIS paketa u kome su korišćena podrazumevana podešavanja, shvatićemo da triger ne radi. Da bismo to demonstrirali kreiraćemo jednostavan SSIS paket koji ima samo jedan Data Flow task koji sadrži po jednu source i destination komponentu.

Source je jednostavan SQL upit koji predstavlja novi crtani film koji želimo da dodamo u tabelu:

SELECT 6 AS CrtacID, 
'Pink Panter' AS Naziv, 
'Pink Panter je izmišljeni lik iz crtanih filmova koji se prvo pojavio kao crtani lik na uvodnoj i završnoj špici serije filmova o inspektoru Kluzou pod imenom „Pink Panter“ iz 60-ih godina 20. veka, da bi nakon sticanja velike popularnosti počeo život u posebnoj seriji crtanih filmova u kojima je on glavni lik.' AS Opis, 
GETDATE() AS DatumIzmene;

, a destination je kreiran tako što je samo izabrana tabela CrtaniFilmovi kao destinaciona tabela, bez promene drugih parametera, što znači da je kao Data access mode ostala opcija Table or view – fast load, što je podrazumevano podešavanje i u najvećem broju slučajeva se koristi upravo ovo podešavanje:

Kada pokrenemo ovako kreirani SSIS paket on će se uspešno izvršiti i dodati novi red u tabelu CrtaniFilmovi, ali na naše iznenađenje to neće biti ulogovano u tabeli log_insert. Da li to znači da nešto nije u redu sa našim trigerom? Odgovor je: NE. Problem nije u trigeru. Problem je u SSIS paketu. Podešavanje Table or view – fast load onemogućava aktiviranje trigera, upravo zbog toga što je cilj izvršiti brz upis podataka, a triger to usporava. Fast load podešavanje kao posledicu ima bulk insert u tabelu i u tom slučaju triger ne radi. Da bismo omogućili aktiviranje trigera, potrebno je Data access mode promeniti na Table or view. Ovo će omogućiti normalno funkcionisanje trigera, pošto se u tom slučaju u tabelu upisuje red po red.

Pored opisanog rešenja, postoji još jedna mogućnost za aktiviranje trigera, čak i kada je izabrana opcija Table or view – fast load. Potrebno je otići u Advanced Editor destinacione komponente što se postiže desnim klikom na nju i izborom opcije Show Advanced Editor iz menija:

Kada se editor otvori, izabere se kartica Component Properties i u vrednost podešavanja FastLoadOptions se doda opcija FIRE_TRIGGERS:

Kada napravimo jednu od dve opisane izmene u podešavanjima i ponovo izvršimo paket (pre toga je poželjno izbrisati već dodati crtani film Pink Panter), videćemo da je u tabeli log_insert uspešno ulogovano dodavanje novog reda u tabelu.

Komentari (2)

Dragi Miloše,
hvala za jasno objašnjenje odnosa i ponašanja na relaciji AFTER INSERT triger SSIS bulk insert fast load FIRE_TRIGGERS opcija.
Medjutim, postoji proširenje ovog problema, kada se SSIS paket pozove iz job-a.

Ako nije uključena opcija FIRE_TRIGGERS job puca sa porukom:
ALTER TABLE permission is required on the target table of a bulk copy operation if the table has triggers or check constraints, but ‘FIRE_TRIGGERS’ or ‘CHECK_CONSTRAINTS’ bulk hints are not specified as options to the bulk copy command.