SQL-utløser eksempler. Databaseutløsere

Definisjonen av en utløser, omfanget av dens bruk, plasseringen og rollen til utløseren for å sikre dataintegritet er gitt. Typer triggere er beskrevet. Operatorer for å opprette, endre og slette en utløser vurderes. Triggerprogrammering er illustrert med eksempler på å lage triggere for å implementere integritetsbegrensninger og samle inn statistiske data.

Utløserdefinisjon i SQL Language Standard

Triggere er en type lagret prosedyre. De utføres når en DML-operator (datamanipulation language) kjøres på bordet. Triggere brukes til å sjekke dataintegritet og også for å rulle tilbake transaksjoner.

En trigger er en kompilert SQL-prosedyre, hvis utførelse er forårsaket av forekomsten av visse hendelser i en relasjonsdatabase. Bruken av triggere er for det meste veldig praktisk for databasebrukere. Likevel innebærer bruken ofte ekstra ressurskostnader for I/O-operasjoner. Når de samme resultatene (med mye mindre overhead) kan oppnås ved å bruke lagrede prosedyrer eller applikasjonsprogrammer, er det ikke praktisk å bruke triggere.

Triggere er et spesielt SQL-serververktøy som brukes til å opprettholde integriteten til data i en database. Integritetsbegrensninger, regler og standarder oppnår kanskje ikke alltid ønsket funksjonalitetsnivå. Det er ofte nødvendig å implementere komplekse dataverifiseringsalgoritmer for å sikre deres pålitelighet og realitet. I tillegg må du noen ganger overvåke endringer i tabellverdier slik at de tilknyttede dataene kan endres etter behov. Triggere kan betraktes som en slags filtre som trer i kraft etter at alle operasjoner er utført i henhold til regler, standardverdier osv.

En trigger er en spesiell type lagret prosedyre som startes automatisk av serveren når det gjøres et forsøk på å endre data i tabellene som utløserne er knyttet til. Hver utløser er knyttet til en bestemt tabell. Alle dataendringer den gjør betraktes som én transaksjon. Hvis det oppdages en feil eller brudd på dataintegriteten, rulles transaksjonen tilbake. Endringer er derfor forbudt. Eventuelle endringer som allerede er gjort av utløseren, blir også angret.

Bare databaseeieren kan opprette en utløser. Denne begrensningen lar deg unngå tilfeldige endringer i strukturen til tabeller, måter å koble andre objekter til dem på, etc.

Utløseren er et veldig nyttig og samtidig farlig verktøy. Så hvis logikken i operasjonen er feil, kan du enkelt ødelegge en hel database, så utløsere må feilsøkes veldig nøye.

I motsetning til en vanlig rutine, utføres en trigger implisitt hver gang den oppstår. utløsende hendelse, dessuten har det ingen argumenter. Å aktivere den kalles noen ganger å avfyre ​​en utløser. Ved å bruke triggere oppnås følgende mål:

  • Validere riktigheten av data som er lagt inn og håndheve komplekse dataintegritetsbegrensninger som er vanskelige, om ikke umulige, å opprettholde ved å bruke integritetsbegrensninger satt på en tabell;
  • utstede advarsler som minner deg om å utføre visse handlinger når du oppdaterer en tabell implementert på en bestemt måte;
  • akkumulering av revisjonsinformasjon ved å registrere informasjon om endringene som er gjort og de personene som utførte dem;
  • replikeringsstøtte.

Det grunnleggende formatet til CREATE TRIGGER-kommandoen er vist nedenfor:

<Определение_триггера>::= LAG TRIGGER trigger_name FØR | ETTER<триггерное_событие>PÅ<имя_таблицы> <тело_триггера>

utløse hendelser bestå av å sette inn, slette og oppdatere rader i en tabell. I sistnevnte tilfelle for utløsende hendelse Du kan angi spesifikke tabellkolonnenavn. Tidspunktet for en utløser bestemmes ved hjelp av nøkkelordene FØR (utløseren utløses før hendelsene knyttet til den blir utført) eller ETTER (etter at de er utført).

Handlingene som utføres av utløseren er spesifisert for hver rad (FOR HVER RAD) som dekkes av en gitt hendelse, eller bare én gang for hver hendelse (FOR HVER STATEMENT).

Betegnelse <список_старых_или_новых_псевдонимов> refererer til komponenter som gammel eller ny rad (GAMMEL / NY) eller gammel eller ny tabell (GAMMEL TABELL / NY TABELL). Det er klart at de gamle verdiene ikke gjelder for å sette inn hendelser, og de nye verdiene gjelder ikke for å slette hendelser.

Når de brukes riktig, kan triggere være en veldig kraftig mekanisme. Deres største fordel er at standardfunksjoner lagres i databasen og aktiveres konsekvent hver gang den oppdateres. Dette kan i stor grad forenkle applikasjoner. Imidlertid er det verdt å nevne de iboende ulempene ved utløseren:

  • kompleksitet: når noen funksjoner flyttes inn i databasen, blir oppgavene med design, implementering og administrasjon mer komplekse;
  • Skjult funksjonalitet: Å flytte noe funksjonalitet inn i en database og lagre den som en eller flere utløsere, resulterer noen ganger i at noe funksjonalitet blir skjult for brukeren. Selv om dette til en viss grad forenkler driften, kan det dessverre forårsake utilsiktede, potensielt uønskede og skadelige bivirkninger, siden brukeren i dette tilfellet ikke er i stand til å kontrollere alle prosessene som skjer i databasen;
  • ytelsespåvirkning: før du utfører hver kommando for å endre tilstanden til databasen, må DBMS sjekke triggertilstanden for å avgjøre om en trigger skal utløses for denne kommandoen. Å utføre slike beregninger påvirker den generelle ytelsen til DBMS, og i perioder med toppbelastning kan reduksjonen bli spesielt merkbar. Når antallet utløsere øker, øker selvsagt også de faste kostnadene forbundet med slike operasjoner.

Feilskrevne triggere kan føre til alvorlige problemer, for eksempel låsninger. Utløsere kan blokkere mange ressurser i lange perioder, så spesiell oppmerksomhet bør rettes mot å minimere tilgangskonflikter.

Implementering av triggere i MS SQL Server-miljø

MS SQL Server DBMS-implementeringen bruker følgende utløseropprettings- eller modifikasjonsoperatør:

<Определение_триггера>::= (OPPRETT | ENDRE) TRIGGER utløsernavn PÅ (tabellnavn | visningsnavn) ( ( ( FOR | ETTER | I STEDET FOR ) ( [ SLETT] [,] [ INSERT] [,] [ OPPDATERING] ) [ MED TILLEGG ] [ IKKE FOR REPLICATION ] AS sql_statement[...n] ) | ( (FOR | ETTER | I STEDET FOR ) ( [,] ) [ WITH APPEND] [ NOT FOR REPLICATION] AS ( IF UPDATE(column_name) [ (OG | OR) UPDATE( column_name)] [...n] | IF (COLUMNS_UPDATES() (prosess_bit_operator) change_bit_mask) (comparison_bit_operator) bit_mask [...n]) sql_operator [...n] ) )

En trigger kan bare opprettes i den gjeldende databasen, men det er mulig å få tilgang til andre databaser innenfor triggeren, inkludert de som ligger på en ekstern server.

La oss se på formålet med argumentene fra CREATE | ENDRE TRIGGER.

Utløsernavnet må være unikt i databasen. I tillegg kan du spesifisere eierens navn.

Når du spesifiserer WITH ENCRYPTION-argumentet, krypterer serveren utløserkoden slik at ingen, inkludert en administrator, kan få tilgang til eller lese den. Kryptering brukes ofte for å skjule proprietære databehandlingsalgoritmer som er programmererens intellektuelle eiendom eller en forretningshemmelighet.

Triggertyper

Det er to alternativer i SQL Server som bestemmer oppførselen til utløsere:

  • ETTER. Utløseren utføres etter at kommandoene som kalte den er fullført. Hvis kommandoene av en eller annen grunn ikke kan fullføres, blir ikke utløseren utført. Det skal bemerkes at dataendringer som følge av utførelse av en brukerforespørsel og utløserutførelse utføres i kroppen til én transaksjon: hvis utløseren rulles tilbake, vil brukerendringer også bli avvist. Du kan definere flere ETTER-utløsere for hver operasjon (INSERT, UPDATE, DELETE). Hvis du har flere AFTER-utløsere på en tabell, kan du bruke sp_settriggerorder-systemets lagrede prosedyre for å spesifisere hvilken utløser som skal kjøre først og hvilken som kjører sist. Som standard, i SQL Server, er alle utløsere ETTER-utløsere.
  • I STEDET FOR . Utløseren kalles i stedet for å utføre kommandoer. I motsetning til ETTER-utløseren, kan INSTEAD OF-utløseren defineres for både en tabell og en visning. For hver INSERT, UPDATE, DELETE-operasjon kan bare én ISTEDEN FOR-utløser defineres.

Triggere kjennetegnes av typen kommandoer de reagerer på.

Det er tre typer triggere:

  • INSERT TRIGGER – Utløses når det gjøres et forsøk på å sette inn data ved hjelp av INSERT-kommandoen.
  • UPDATE TRIGGER – utløses når det gjøres et forsøk på å endre data ved hjelp av UPDATE-kommandoen.
  • DELETE TRIGGER – utløses når det gjøres et forsøk på å slette data ved hjelp av DELETE-kommandoen.

Konstruksjoner [ SLETT] [,] [ SETT INN] [,] [ OPPDATERING] Og FOR | ETTER | I STEDET FOR ) ([,] bestemme hvilken kommando utløseren vil svare på. Når du oppretter den, må minst én kommando spesifiseres. Tillatt lage en trigger, svarer på to eller alle tre kommandoene.

MED APPEND lar deg lage flere triggere av hver type.

lage en trigger med IKKE FOR REPLIKASJON-argumentet, er det forbudt å kjøre mens tabeller blir modifisert av replikeringsmekanismer.

AS sql_operator[...n]-konstruksjonen definerer et sett med SQL-setninger og kommandoer som vil bli utført når triggeren startes.

Merk at en rekke operasjoner ikke er tillatt inne i en utløser, for eksempel:

  • opprette, endre og slette en database;
  • gjenopprette en sikkerhetskopi av database eller transaksjonslogg.

Disse kommandoene har ikke lov til å utføres fordi de ikke kan rulles tilbake hvis transaksjonen der utløseren ble utført, rulles tilbake. Dette forbudet vil neppe på noen måte påvirke funksjonaliteten til opprettede utløsere. Det er vanskelig å finne en situasjon der du for eksempel, etter å ha endret en tabellrad, må gjenopprette en sikkerhetskopi av transaksjonsloggen.

Trigger programmering

Når du utfører kommandoer for å legge til, endre og slette poster, oppretter serveren to spesielle tabeller: satt inn Og slettet. De inneholder lister over rader som vil bli satt inn eller slettet når transaksjonen er fullført. Strukturen til de innsatte og slettede tabellene er identisk med strukturen til tabellene som utløseren er definert for. Hver utløser oppretter sitt eget sett med innsatte og slettede tabeller, slik at ingen andre utløsere har tilgang til dem. Avhengig av typen operasjon som fikk utløseren til å utføre, kan innholdet i de innsatte og slettede tabellene være forskjellig:

  • INSERT kommando – den innsatte tabellen inneholder alle radene som brukeren prøver å sette inn i tabellen; det vil ikke være en eneste rad i den slettede tabellen; etter at utløseren er fullført, vil alle rader fra den innsatte tabellen flyttes til kildetabellen;
  • DELETE kommando – den slettede tabellen vil inneholde alle rader som brukeren prøver å slette; utløseren kan sjekke hver rad og bestemme om den er tillatt å slettes; det vil ikke være noen rader i den innsatte tabellen;
  • UPDATE-kommando - når den utføres, inneholder den slettede tabellen gamle radverdier som vil bli slettet ved vellykket fullføring av utløseren. De nye radverdiene finnes i den innsatte tabellen. Disse radene vil bli lagt til i kildetabellen etter at triggeren er utført.

For å få informasjon om antall rader som vil bli endret når en trigger fullføres, kan du bruke @@ROWCOUNT;-funksjonen. den returnerer antall rader behandlet av den siste kommandoen. Det skal understrekes at utløseren ikke utløses når det gjøres et forsøk på å endre en spesifikk linje, men i det øyeblikket endringskommandoen utføres. En slik kommando påvirker mange rader, så utløseren må behandle alle disse radene.

Hvis utløseren oppdager at av 100 rader som settes inn, endres eller slettes, er det bare én som ikke tilfredsstiller visse betingelser, vil ingen rad bli satt inn, endret eller slettet. Denne oppførselen skyldes transaksjonens krav - enten må alle modifikasjoner utføres eller ingen.

En utløser utføres som en implisitt definert transaksjon, så transaksjonskontrollkommandoer kan brukes i utløseren. Nærmere bestemt, når et brudd på integritetsbegrensningen oppdages, må ROLLBACK TRANSACTION-kommandoen brukes til å avbryte utløseren og angre eventuelle endringer brukeren forsøkte å gjøre.

Du kan bruke funksjonen COLUMNS_UPDATED() for å få en liste over kolonner som ble modifisert av INSERT- eller UPDATE-kommandoene som fikk utløseren til å kjøre. Den returnerer et binært tall, hvor hver bit, starter med den minst signifikante biten, tilsvarer én kolonne i tabellen (i rekkefølgen til kolonnene da tabellen ble opprettet). Hvis en bit er satt til "1", er den tilsvarende kolonnen endret. I tillegg bestemmes det at en kolonne er endret av OPPDATERING-funksjonen (kolonnenavn).

Til fjern utløseren kommandoen brukes

DROP TRIGGER (trigger_name) [,...n]

Her er eksempler på bruk av triggere.

Eksempel 14.1. Bruke en trigger for å implementering av verdirestriksjoner. I oppføringen som er lagt til i Transaksjonstabellen, må mengden av det solgte produktet ikke være mindre enn saldoen fra Lager-tabellen.

Kommandoen for å sette inn en post i Deal-tabellen kan for eksempel være slik:

INSERT INTO Trade VALUES (3,1,-299,"01/08/2002")

Den opprettede utløseren skal reagere på utføringen av den på følgende måte: det er nødvendig å avbryte kommandoen hvis produktbalansen i lagertabellen er mindre enn den solgte mengden av produktet med den angitte koden (i eksempelet, produktkode = 3 ). I den innsatte posten er mengden av produktet angitt med et "+"-tegn hvis produktet er levert, og med et "-"-tegn hvis det selges. Den presenterte utløseren er konfigurert til å behandle bare én lagt til post.

LAG TRIGGER Trigger_ins PÅ transaksjon FOR INSERT AS IF @@ROWCOUNT=1 BEGIN IF NOT EXISTS(SELECT * FROM inserted WHERE -inserted.quantity<=ALL(SELECT Склад.Остаток FROM Склад,Сделка WHERE Склад.КодТовара= Сделка.КодТовара)) BEGIN ROLLBACK TRAN PRINT "Отмена поставки: товара на складе нет" END END Eksempel 14.1. Bruke en trigger for å implementere begrensninger på en verdi.

Eksempel 14.2. Bruke en trigger for å samle inn statistiske data.

Opprett en trigger for å behandle operasjonen med å sette inn en post i Deal-tabellen, for eksempel følgende kommando:

SETTE INN I HandelsVERDIER (3,1,200,"01/08/2002")

Produkt med kode 3 leveres fra kunde med kode 1 i mengden 200 enheter.

Ved salg eller mottak av en vare skal lagermengden justeres tilsvarende. Hvis produktet ennå ikke er på lager, må du legge til en tilsvarende oppføring i lagertabellen. Utløseren behandler bare én lagt til rad.

ALTER TRIGGER Trigger_ins PÅ Transaksjon FOR INSERT AS DECLARE @x INT, @y INT IF @@ROWCOUNT=1 --en post legges til Transaksjonstabellen om levering av varer BEGIN --mengden solgte varer må ikke være -- mindre enn saldoen fra varehustabellen HVIS IKKE FINNES(VELG * FRA satt inn WHERE -innsatt.antall< =ALL(SELECT Склад.Остаток FROM Склад,Сделка WHERE Склад.КодТовара= Сделка.КодТовара)) BEGIN ROLLBACK TRAN PRINT "откат товара нет " END --если записи о поставленном товаре еще нет, --добавляется соответствующая запись --в таблицу Склад IF NOT EXISTS (SELECT * FROM Склад С, inserted i WHERE С.КодТовара=i.КодТовара) INSERT INTO Склад (КодТовара,Остаток) ELSE --если запись о товаре уже была в таблице --Склад, то определяется код и количество --товара издобавленной в таблицу Сделка записи BEGIN SELECT @y=i.КодТовара, @x=i.Количество FROM Сделка С, inserted i WHERE С.КодТовара=i.КодТовара --и производится изменения количества товара в --таблице Склад UPDATE Склад SET Остаток=остаток+@x WHERE КодТовара=@y END END Eksempel 14.2. Bruke en trigger for å samle inn statistiske data.

Eksempel 14.3. Opprett en trigger for å behandle operasjonen med å slette en post fra Deal-tabellen, for eksempel følgende kommando:

For produktet hvis kode ble spesifisert da posten ble slettet, er det nødvendig å justere lagerbalansen. Utløseren behandler bare én post som skal slettes.

OPPRETT TRIGGER Trigger_del PÅ Transaksjon FOR SLETT SOM OM @@ROWCOUNT=1 -- én post er slettet BEGYNNE DEKLARER @y INT,@x INT --koden og antallet av produktet bestemmes fra posten -- slettet fra lagertabellen VELG @y=Produktkode, @ x=Antall FRA slettet --i lagertabellen er mengden av --vare justert OPPDATERING Lagersett Resterende=Resterende-@x HVOR Produktkode=@y END Eksempel 14.3. Trigger for å behandle operasjonen med å slette en post fra en tabell

Eksempel 14.4. Opprett en utløser for å behandle operasjonen med å endre en post i Deal-tabellen, for eksempel med følgende kommando:

i alle transaksjoner med varer med en kode lik 3, reduser varemengden med 10 enheter.

Den angitte kommandoen kan føre til endringer i flere poster samtidig i Deal-tabellen. Derfor vil vi vise hvordan du oppretter en trigger som behandler mer enn én post. For hver endret oppføring er det nødvendig for den gamle (før endringen) produktkoden å redusere saldoen til produktet på lageret med verdien av den gamle (før endringen) kvantum av produktet og for den nye (etter endring) produktkode for å øke saldoen på lageret med verdien av den nye verdien (etter endringen). For å behandle alle endrede poster, vil vi introdusere markører der vi lagrer alle gamle (fra den slettede tabellen) og alle nye verdier (fra den innsatte tabellen).

LAG TRIGGER Trigger_upd PÅ Transaksjon FOR OPPDATERING SOM DECLARE @x INT, @x_old INT, @y INT, @y_old INT -- markør med nye verdier DECLARE CUR1 CURSOR FOR SELECT Produktkode, mengde FRA satt inn -- markør med gamle verdier ​​ERKLÆR CUR2-MARKØR FOR VALG produktkode, mengde FRA slettet OPEN CUR1 OPEN CUR2 -- flytt parallelt gjennom begge markørene FETCH NEXT FROM CUR1 INTO @x, @y FETCH NEXT FROM CUR2 INTO @x_old, @y_old WHILE @@FETCH_STATUS= BEGIN -- for den gamle produktkoden reduseres den -- kvantumet på lageret OPPDATERING Lager SET Remaining=Remaining-@y_old WHERE Produktkode=@x_old --for en ny produktkode, hvis et slikt produkt ennå ikke er på lager, en ny post legges inn HVIS IKKE FINNES (VELG * FRA Varehus HVOR Produktkode=@x) INSERT INTO Warehouse(Produktkode, Gjenstående) VERDIER (@x,@y) ELLERS -- ellers øker den for en ny produktkode -- dens mengde på lager OPPDATERING VarehusSETT Resterende=Gjenstående+@y HVOR Produktkode=@x HENT NESTE FRA CUR1 TIL @x, @y HENT NESTE FRA CUR2 TIL @x_old, @y_old SLUTT LUKK CUR1 CLOSE CUR2 AVALLOKERE CUR1 DEALLOCATE CUR1 Eksempel 14.4. trigger for å behandle en operasjon for å endre en post i en tabell

I den betraktede utløseren er det ingen sammenligning av varemengden når en transaksjonspost endres med saldoen på lageret.

Eksempel 14.5. La oss rette opp denne mangelen. For å generere en feilmelding bruker vi MS SQL Server RAISERROR-kommandoen i kroppen til utløseren, hvis argumenter er meldingstekst, alvorlighetsgrad og feilstatus.

ENDRE TRIGGER Trigger_upd PÅ Transaksjon FOR OPPDATERING SOM DECLARE @x INT, @x_old INT, @y INT, @y_old INT ,@o INT DECLARE CUR1 CURSOR FOR SELECT Item Code, Quantity FROM insertARE DECLARE CUR2 CURSOR FOR SELECT FRA Varekode, mengde OPEN CUR1 OPEN CUR2 HENT NESTE FRA CUR1 INTO @x, @y FETCH NEXT FROM CUR2 INTO @x_old, @y_old MENS @@FETCH_STATUS=0 BEGYNNE VELG @o=gjenstår FRA lager HVOR produktkode=@x IF @o<-@y BEGIN RAISERROR("откат",16,10) CLOSE CUR1 CLOSE CUR2 DEALLOCATE CUR1 DEALLOCATE CUR22 ROLLBACK TRAN RETURN END UPDATE Склад SET Остаток=Остаток-@y_old WHERE КодТовара=@x_old IF NOT EXISTS (SELECT * FROM Склад WHERE КодТовара=@x) INSERT INTO Склад(КодТовара,Остаток) VALUES (@x,@y) ELSE UPDATE Склад SET Остаток=Остаток+@y WHERE КодТовара=@x FETCH NEXT FROM CUR1 INTO @x, @y FETCH NEXT FROM CUR2 INTO @x_old, @y_old END CLOSE CUR1 CLOSE CUR2 DEALLOCATE CUR1 DEALLOCATE CUR2 Eksempel 14.5. Korrigert versjon av utløseren for å behandle operasjonen med å endre en post i en tabell

Eksempel 14.6. I eksemplet blir alle endringer kansellert hvis det er umulig å implementere minst én av dem. La oss lage en trigger som lar deg avbryte endringer i bare noen poster og endre resten.

I dette tilfellet utføres ikke utløseren etter at postene er endret, men i stedet for endringskommandoen.

ENDRE TRIGGER Trigger_upd PÅ transaksjon I STEDET FOR OPPDATERING SOM DECLARE @k INT, @k_old INT DECLARE @x INT, @x_old INT, @y INT DECLARE @y_old INT ,@o INT DECLARE CUR1 CURSOR FOR SELECT Transaction Code, Product Code, Quantity FROM satt inn DECLARE CUR2 CURSOR FOR SELECT Transaction Code, Product Code, Quantity FROM slettet OPEN CUR1 OPEN CUR2 FETCH NEXT FROM CUR1 INTO @k,@x, @y FETCH NEXT FROM CUR2 INTO @k_old,@x_old, @y_old WHILE @TUS= 0 BEGIN SELECT @ o=resterende FRA lager HVOR Produktkode=@x HVIS @o>=-@y BEGIN RAISERROR("endre",16,10) OPPDATERING Transaksjonssett kvantitet=@y, Produktkode=@x HVOR Transaksjonskode =@k OPPDATERING VarehusSETT Gjenværende =Remaining-@y_old HVOR Varekode=@x_old HVIS IKKE FINNES (VELG * FRA lager HVOR Varekode=@x) INSERT INTO Warehouse(Varekode, Gjenværende) VERDIER (@x,@y) ELSE UPDATE Warehouse SET Remaining=Remaining+@y WHERE Item Code=@x END ELSE RAISERROR("record not change",16,10) FETCH NEXT FROM CUR1 INTO @k,@x, @y FETCH NEXT FROM CUR2 INTO @k_old, @x_old, @y_old SLUTT CLOSE CUR1 CLOSE CUR2 DEALLOCATE CUR1 DEALLOCATE CUR2 Eksempel 14.6. En trigger som lar deg angre endringer i bare noen poster og gjøre endringer i resten.

333 163

Den foregående syntaksen gjelder bare for DML-utløsere. DDL-utløsere har en litt annen form for syntaks, som vil bli vist senere.

Her spesifiserer schema_name-parameteren navnet på skjemaet som triggeren tilhører, og trigger_name-parameteren spesifiserer navnet på triggeren. Tabellnavn-parameteren spesifiserer navnet på tabellen som utløseren er opprettet for. (Utløsere for visninger støttes også, som indikert av tilstedeværelsen av parameteren view_name.)

Du kan også stille inn triggertypen ved å bruke to ekstra parametere: ETTER og I STEDET FOR. (FOR-parameteren er et synonym for AFTER-parameteren.) ETTER-type utløses kalles etter at handlingen som utløser utløseren er utført, og I STEDET FOR typeutløsere utføres i stedet for handlingen som utløser utløseren. ETTER-utløsere kan kun opprettes på tabeller, mens ISTEDEN FOR utløsere kan opprettes på både tabeller og visninger.

Parameterne INSERT, UPDATE og DELETE spesifiserer utløserhandlingen. Utløserhandling refererer til Transact-SQL-setningen som utløser utløseren. Enhver kombinasjon av disse tre instruksjonene er tillatt. DELETE-setningen er ikke tillatt hvis alternativet IF UPDATE brukes.

Som du kan se i syntaksen til CREATE TRIGGER-setningen, er triggerhandlingen (eller handlingene) spesifisert i AS sql_statement-spesifikasjonen.

Databasemotoren lar deg lage flere utløsere per tabell og per handling (INSERT, UPDATE og DELETE). Som standard er det ingen spesifikk rekkefølge for utførelse av flere utløsere for en gitt endringshandling.

Bare databaseeieren, DDL-administratorene og eieren av tabellen som utløseren er definert på har tillatelse til å opprette utløsere for gjeldende database. (I motsetning til tillatelser for andre typer CREATE-setninger, kan ikke denne tillatelsen overføres.)

Endre triggerstrukturen

Transact-SQL støtter også uttalelsen ENDRE TRIGGER, som endrer utløserstrukturen. Denne instruksjonen brukes vanligvis til å endre kroppen til en utløser. Alle ledd og parametere i ALTER TRIGGER-setningen har samme betydning som de samme leddene og parameterne til CREATE TRIGGER-setningen.

For å fjerne utløsere i gjeldende database, bruk setningen SLIPPE TRIGGER.

Bruk av slettede og innsatte virtuelle tabeller

Når du oppretter en utløserhandling, må du vanligvis spesifisere om den refererer til en kolonneverdi før eller etter at den endres av handlingen som utløser utløseren. Av denne grunn brukes to spesielt navngitte virtuelle tabeller for å teste effekten av setningen som utløser utløseren:

    slettet - inneholder kopier av rader slettet fra tabellen;

    satt inn - inneholder kopier av rader som er satt inn i tabellen.

Strukturen til disse tabellene tilsvarer strukturen til tabellen som utløseren er definert for.

Tabell slettet brukes hvis CREATE TRIGGER-setningen spesifiserer en DELETE- eller UPDATE-klausul, og hvis setningen spesifiserer en INSERT- eller UPDATE-klausul, tabell satt inn. Dette betyr at for hver DELETE-setning som utføres i en utløserhandling, opprettes en slettet tabell. På samme måte, for hver INSERT-setning som utføres i en utløserhandling, opprettes en innsatt tabell.

UPDATE-setningen behandles som en DELETE-setning etterfulgt av en INSERT-setning. Derfor, for hver UPDATE-setning som utføres i en utløserhandling, opprettes både en slettet tabell og en innsatt tabell (i den rekkefølgen).

De innsatte og slettede tabellene implementeres ved hjelp av radversjon, som ble diskutert i forrige artikkel. Når en DML-setning (INSERT, UPDATE eller DELETE) kjøres på en tabell med passende utløsere, opprettes alltid radversjoner for alle endringer i den tabellen. Når en utløser trenger informasjon fra den slettede tabellen, får den tilgang til dataene i radversjonslageret. Når det gjelder en innsatt tabell, får utløseren tilgang til de nyeste versjonene av radene.

Radversjonsmotoren bruker tempdb-systemdatabasen som radversjonslager. Av denne grunn, hvis en database inneholder et stort antall ofte brukte utløsere, kan du forvente en betydelig økning i størrelsen på den systemdatabasen.

Bruksområder for DML-triggere

Slike triggere brukes til å løse en rekke problemer. I denne delen skal vi se på flere bruksområder for DML-utløsere, spesielt ETTER- og ISTEDEN FOR-utløsere.

ETTER triggere

Som du allerede vet, utløses AFTER-utløsere etter at handlingen som utløser utløseren er utført. En ETTER-utløser spesifiseres ved hjelp av nøkkelordet AFTER eller FOR. ETTER-utløsere kan bare opprettes på basistabeller. Triggere av denne typen kan blant annet brukes til å utføre følgende operasjoner:

    lage en logg over handlingslogger i databasetabeller;

    implementering av forretningsregler;

    håndheving av referanseintegritet.

Opprette en logglogg

I SQL Server kan du utføre endringsdatafangst ved hjelp av CDCs endringsdatafangstsystem. Dette problemet kan også løses ved hjelp av DML-utløsere. Eksemplet nedenfor viser hvordan triggere kan brukes til å lage en logg over aktivitetslogger i databasetabeller:

BRUK SampleDb; /* Tabellen AuditBudget brukes som en logg over aktivitetslogger i Project-tabellen */ GO CREATE TABLE AuditBudget (ProjectNumber CHAR(4) NULL, UserName CHAR(16) NULL, Date DATETIME NULL, BudgetOld FLOAT NULL, BudgetNew FLOAT NULL) ; GÅ OPPRETT TRIGGER trigger_ModifyBudget PÅ Prosjekt ETTER OPPDATERING SOM OM OPPDATERING(budsjett) BEGIN DECLARE @budgetOld FLOAT DECLARE @budgetNew FLOAT DECLARE @projectNumber CHAR(4) SELECT @budgetOld = (VELG budsjett FROM slettet) VELG @budsjettNytt i = (VELG budsjett) SELECT @projectNumber = (VELG nummer FRA slettet) INSERT INTO AuditBudget VALUES (@projectNumber, USER_NAME(), GETDATE(), @budgetOld, @budgetNew) END

Dette eksemplet oppretter en AuditBudget-tabell som lagrer alle endringer i Budsjett-kolonnen i Project-tabellen. Endringer i denne kolonnen vil bli skrevet til denne tabellen ved å bruke trigger_ModifyBudget-utløseren.

Denne utløseren utløses for hver endring i Budsjett-kolonnen ved hjelp av en OPPDATERING. Når denne utløseren utføres, blir de slettede og innsatte tabellradverdiene tilordnet de tilsvarende variablene @budgetOld, @budgetNew og @projectNumber. Disse tildelte verdiene, sammen med brukernavnet og gjeldende dato, vil deretter bli satt inn i AuditBudget-tabellen.

Dette eksemplet forutsetter at bare én rad vil bli oppdatert om gangen. Derfor er dette eksemplet en forenkling av det vanlige tilfellet der en utløser håndterer oppdateringer med flere rader. Hvis du kjører følgende Transact-SQL-setninger:

da vil innholdet i AuditBudget-tabellen være slik:

Implementering av forretningsregler

Ved å bruke triggere kan du lage forretningsregler for applikasjoner. Opprettelsen av en slik utløser er vist i eksemplet nedenfor:

BRUK SampleDb; -- Trigger_TotalBudget er et eksempel på bruk av -- en trigger for å implementere en forretningsregel GÅ OPPRETT TRIGGER trigger_TotalBudget PÅ Prosjekt ETTER OPPDATERING SOM OM OPPDATERING (Budsjett) BEGYNN DEKLARER @sum_old1 FLOAT DEKLARE @sum_old2 FLOAT DEKLARE @sum_new FLOAT VELG @sum_new = (VELG @sum_new = (VELG @sum_old) SELECT SUM( Budsjett) FROM satt inn) VELG @sum_old1 = (VELG SUM(p.Budsjett) FRA prosjekt p WHERE p.Number NOT IN (VELG d.Number FROM slettet d)) SELECT @sum_old2 = (VELG SUM(Budsjett) FRA slettet) HVIS @sum_new > (@sum_old1 + @sum_old2) * 1.5 BEGYNN UTSKRIFT "Budsjett uendret" TILBAKETRANSAKSJON END ELSE UTSKRIFT "Budsjettendring fullført" END

Her oppretter du en regel for å kontrollere endring av prosjektbudsjetter. Trigger_TotalBudget sjekker hver budsjettendring og utfører bare de OPPDATERINGS-uttalelsene som øker summen av alle budsjetter med ikke mer enn 50 %. Ellers rulles UPDATE-setningen tilbake ved hjelp av en ROLLBACK TRANSACTION-setning.

Håndheve integritetsbegrensninger

Databaseadministrasjonssystemer bruker to typer begrensninger for å sikre dataintegritet: deklarative begrensninger, som er definert ved hjelp av språksetningene CREATE TABLE og ALTER TABLE; prosedyremessige integritetsbegrensninger som implementeres gjennom triggere.

I normale situasjoner bør deklarative begrensninger brukes for å sikre integritet fordi de støttes av systemet og ikke krever brukerimplementering. Bruk av triggere anbefales kun i tilfeller der det ikke er noen deklarative begrensninger for å sikre integritet.

Eksemplet nedenfor viser hvordan du håndhever referanseintegritet ved å bruke utløsere i tabellene Employee og Works_on:

BRUK SampleDb; GÅ OPPRETT TRIGGER trigger_WorksonIntegrity ON Works_on ETTER INSERT, UPDATE AS IF UPDATE(EmpId) BEGIN IF (VELG Employee.Id FROM Employee, inserted WHERE Employee.Id = inserted.EmpId) IS NULL PRINT ROLLBACK in BEGIN ROLLBACK in. " END ELSE PRINT "Raden ble satt inn/endret" END

Trigger_WorksonIntegrity i dette eksemplet kontrollerer referanseintegritet for tabellene Employee og Works_on. Dette betyr at hver endring i Id-kolonnen i referansetabellen Works_on blir sjekket og ethvert brudd på denne begrensningen vil ikke tillate at operasjonen fortsetter. (Det samme gjelder for å sette inn nye verdier i Id-kolonnen.) ROLLBACK TRANSACTION-setningen i den andre BEGIN-blokken ruller tilbake INSERT- eller UPDATE-setningen hvis en begrensning brytes for å sikre referanseintegritet.

I dette eksemplet sjekker utløseren for første og andre saks referanseintegritetsproblemer mellom tabellene Employee og Works_on. Og eksemplet nedenfor viser en trigger som sjekker for referanseintegritetsproblemer i det tredje og fjerde tilfellet mellom de samme tabellene (disse tilfellene ble diskutert i artikkelen "Transact-SQL - lage tabeller"):

BRUK SampleDb; GÅ OPPRETT TRIGGER trigger_RefintWorkson2 PÅ ansatt ETTER SLETTING, OPPDATER SOM OM OPPDATERING (Id) BEGIN IF (VELG COUNT(*) FROM Works_on, slettet WHERE Works_on.EmpId = deleted.Id) > 0 BEGIN ROLLBACK TRANSACTION modifisert " END ELSE PRINT "Raden ble satt inn/endret" END

Triggere I STEDET FOR

Tilbudsutløser I STEDET FOR erstatter den tilsvarende handlingen som utløste den. Denne utløseren kjører etter at de tilsvarende innsatte og slettede tabellene er opprettet, men før integritetskontroller eller andre handlinger utføres.

I STEDET FOR kan utløsere opprettes for både tabeller og visninger. Når en Transact-SQL-setning refererer til en visning som har en INSTEAD OF-utløser definert, kjører databasesystemet denne utløseren i stedet for å utføre noen handling på en hvilken som helst tabell. Denne typen utløser bruker alltid informasjonen i de innsatte og slettede tabellene som er opprettet for visningen, for å generere utsagn som kreves for å opprette den forespurte hendelsen.

Kolonneverdiene gitt av INSTEAD OF-utløseren må oppfylle visse krav:

    verdier kan ikke angis for beregnede kolonner;

    verdier kan ikke angis for kolonner av tidsstempeldatatypen;

    verdier kan ikke angis for kolonner med IDENTITY-egenskapen med mindre IDENTITY_INSERT er satt til PÅ.

Disse kravene gjelder bare for INSERT- og UPDATE-setninger som refererer til basistabeller. En INSERT-setning som refererer til visninger med en INSTEAD OF-utløser, må gi verdier for alle kolonner i den visningen som ikke tillater nullverdier. (Det samme gjelder for en UPDATE-setning. En UPDATE-setning som refererer til en visning med en INSTEAD OF-utløser, må gi verdier for alle kolonner i en visning som ikke tillater nullverdier og er referert til i SET-leddet.)

Eksemplet nedenfor viser forskjellen i oppførsel når du setter inn verdier i beregnede kolonner ved hjelp av en tabell og dens tilsvarende visning:

BRUK SampleDb; LAG TABELL Ordrer (OrderId INT NOT NULL, Price MONEY NOT NULL, Quantity INT NOT NULL, OrderDate DATETIME NOT NULL, Total AS Price * Quantity, ShippedDate AS DATEADD (DAY, 7, orderdate)); GÅ OPPRETT VISNING view_AllOrders AS SELECT * FROM Orders; GÅ OPPRETT TRIGGER trigger_orders PÅ view_AllOrders I STEDET FOR INSERT AS BEGIN INSERT INTO Orders SELECT OrderId, Price, Quantity, OrderDate FROM inserted END

Dette eksemplet bruker en ordretabell som inneholder to beregnede kolonner. view_AllOrders inneholder alle radene i denne tabellen. Denne visningen brukes til å angi en verdi i kolonnen som tilordnes en beregnet kolonne i basistabellen som visningen er opprettet på. Dette lar deg bruke en INSTEAD OF-utløser, som i tilfelle av en INSERT-setning erstattes av en batch som setter inn verdier i basistabellen via view_AllOrders-visningen. (En INSERT-setning som får direkte tilgang til basistabellen kan ikke angi en verdi til en beregnet kolonne.)

Trigger først og sist

Databasemotoren lar deg lage flere utløsere for hver tabell eller visning og for hver operasjon (INSERT, UPDATE og DELETE) på dem. I tillegg kan du spesifisere utførelsesrekkefølgen for flere utløsere definert for en bestemt operasjon. Bruke en systemprosedyre sp_settriggerorder Du kan spesifisere at en av AFTER-utløserne som er definert for en tabell, vil bli utført først eller sist for hver handling som behandles. Denne systemprosedyren har en @order-parameter som kan tilordnes én av tre verdier:

    første - indikerer at utløseren er den første ETTER-utløseren som utføres for å endre handlingen;

    siste - indikerer at denne utløseren er den siste ETTER-utløseren som er utført for å starte en handling;

    ingen - indikerer at det ikke er noen spesifikk utførelsesordre for utløseren. (Denne verdien brukes vanligvis til å tilbakestille utløserens tidligere angitte rekkefølge for utførelse som første eller siste.)

Endring av strukturen til en utløser ved å bruke ALTER TRIGGER-setningen reverserer utløserens utførelsesrekkefølge (første eller siste). Følgende eksempel viser bruken av sp_settriggerorder-systemprosedyren:

BRUK SampleDb; EXEC sp_settriggerorder @triggername = "trigger_ModifyBudget", @order = "først", @stmttype="oppdatering"

Du kan definere kun én første og kun én siste ETTER-utløser for en tabell. De resterende ETTER-utløserne utføres i en uspesifisert rekkefølge. Du kan finne ut i hvilken rekkefølge en utløser utføres ved å bruke systemprosedyren sp_helptrigger eller OBJECTPROPERTY-funksjonene.

Resultatsettet som returneres av sp_helptrigger-systemprosedyren inneholder en rekkefølgekolonne som spesifiserer rekkefølgen som den angitte utløseren utføres i. Når du kaller objektegenskapsfunksjonen, er dens andre parameter ExeclsFirstTrigger eller ExeclsLastTrigger, og den første parameteren er alltid ID-nummeret til databaseobjektet. Hvis egenskapen spesifisert i den andre parameteren er sann, returnerer funksjonen verdien 1.

Fordi en INSTEAD OF-utløser kjøres før endringer gjøres i tabellen, kan utløsere av denne typen ikke spesifiseres til å kjøre i første eller siste rekkefølge.

DDL-utløsere og deres applikasjoner

Tidligere har vi sett på DML-utløsere, som spesifiserer handlingen serveren utfører når en tabell er modifisert av en INSERT-, UPDATE- eller DELETE-setning. Databasemotoren lar deg også definere utløsere for DDL-setninger som CREATE DATABASE, DROP TABLE og ALTER TABLE. Utløsere for DDL-setninger har følgende syntaks:

LAG TRIGGER trigger_name PÅ (ALL SERVER | DATABASE ) (FOR | ETTER ) ( hendelsesgruppe | hendelsestype | LOGON) AS (batch | EKSTERNT NAVN metodenavn) Syntakskonvensjoner

Som du kan se fra deres syntaks, er DDL-utløsere opprettet på samme måte som DML-utløsere. Og for å endre og slette disse triggerne, brukes de samme ALTER TRIGGER- og DROP TRIGGER-setningene som for DML-utløsere. Derfor diskuterer denne delen bare de parameterne i CREATE TRIGGER-setningen som er nye for DDL-utløsersyntaksen.

Det første trinnet når du definerer en DDL-utløser, er å spesifisere omfanget. DATABASE-klausul spesifiserer gjeldende database som omfanget av DDL-utløseren, og ALL SERVER-tilbud- gjeldende server.

Etter å ha spesifisert omfanget av en DDL-utløser, må du spesifisere hvordan utløseren skal utløses som svar på kjøringen av én eller flere DDL-setninger. Event_type-parameteren spesifiserer DDL-setningen som, når den kjøres, utløser triggeren, og event_group alternative parameter spesifiserer Transact-SQL-hendelsesgruppen. En DDL-utløser utløses etter utførelse av enhver Transact-SQL-hendelse spesifisert i parameteren event_group. Nøkkelord LOGG PÅ indikerer inngangsutløseren.

Foruten likhetene mellom DML- og DDL-utløsere, er det også flere forskjeller mellom dem. Hovedforskjellen mellom disse to typene triggere er at en DDL-utløser kan scopes til hele databasen eller til og med hele serveren, i stedet for bare et enkelt objekt. I tillegg støtter ikke DDL-triggere I STEDET FOR triggere. Som du kanskje har gjettet, krever ikke DDL-utløsere innsatte og slettede tabeller fordi disse utløserne ikke endrer innholdet i tabellene.

Følgende underavsnitt diskuterer i detalj de to formene for DDL-utløsere: utløsere på databasenivå og utløsere på servernivå.

DDL-utløsere på databasenivå

Eksemplet nedenfor viser hvordan du kan implementere en DDL-utløser hvis omfang strekker seg til gjeldende database:

BRUK SampleDb; GÅ OPPRETT TRIGGER trigger_PreventDrop PÅ DATABASE FOR DROP_TRIGGER SOM SKRIV UT "Før du kan slette en trigger, må du deaktivere "trigger_PreventDrop"" ROLLBACK

Utløseren i dette eksemplet forhindrer enhver bruker i å slette en utløser på SampleDb-databasen. DATABASE-leddet spesifiserer at trigger_PreventDrop er en utløser på databasenivå. Nøkkelord DROP_TRIGGER angir en forhåndsdefinert hendelsestype som forhindrer at en utløser slettes.

DDL-utløsere på servernivå

Utløsere på servernivå reagerer på hendelser på serversiden. En utløser på servernivå opprettes ved å bruke ALL SERVER-leddet i CREATE TRIGGER-setningen. Avhengig av handlingen triggeren utfører, er det to forskjellige typer utløsere på servernivå: vanlige DDL-utløsere og påloggingsutløsere. Utløsningen av vanlige DDL-triggere er basert på DDL-setningshendelser, mens utløsningen av entry-triggere er basert på entry-hendelser.

Eksemplet nedenfor viser hvordan du oppretter en utløser på servernivå som er en påloggingsutløser:

BRUK master; GÅ OPPRETT LOGG PÅ loginTest MED PASSORD = "12345!", CHECK_EXPIRATION = PÅ; GÅ GI VIS SERVER STATE FOR å logge innTest; Gå opprett trigger trigger_connectionlimit på alle serveren med utførelse som "logintest" for pålogging som begynner hvis original_login () = "logintest" og (velg count (*) fra sys.dm_exec_sessions der is_user_process = 1 og original_login_name = "logintest")> 1 roll roll Rollen. ; SLUTT;

Her opprettes først SQL Server loginTest, som deretter brukes i en utløser på servernivå. Av denne grunn krever denne påloggingen VIEW SERVER STATE-tillatelse, som er gitt til den gjennom GRANT-setningen. Etter dette opprettes trigger_ConnectionLimit. Denne utløseren er en påloggingsutløser, som indikert av LOGON-nøkkelordet.

Bruker Vis sys.dm_exec_sessions det foretas en sjekk for å se om en økt allerede er etablert ved hjelp av loginTest-påloggingen. Hvis økten allerede er etablert, utføres ROLLBACK-setningen. Derfor kan loginTest-påloggingen bare opprette én økt om gangen.

Triggere og CLR

I likhet med lagrede prosedyrer og brukerdefinerte funksjoner, kan utløsere implementeres ved å bruke Common Language Runtime (CLR). Triggere i CLR opprettes i tre trinn:

    Utløserkildekoden genereres i C# eller Visual Basic, som deretter kompileres ved hjelp av riktig kompilator til objektkode.

    Objektkoden behandles med CREATE ASSEMBLY-setningen, og skaper en tilsvarende kjørbar fil.

    CREATE TRIGGER-setningen oppretter en trigger.

Følgende eksempler viser alle tre trinnene for å lage en CLR-utløser. Nedenfor er et eksempel på C#-programmets kildekode for triggeren fra det første eksemplet i artikkelen. Før du oppretter en CLR-utløser i de følgende eksemplene, må du først fjerne trigger_PreventDrop-utløseren og deretter fjerne trigger_ModifyBudget-utløseren, ved å bruke DROP TRIGGER-setningen i begge tilfeller.

Bruke System; bruker System.Data.SqlClient; bruker Microsoft.SqlServer.Server; public class Triggers ( public static void ModifyBudget() ( SqlTriggerContext context = SqlContext.TriggerContext; if (context.IsUpdatedColumn(2)) // Budsjettkolonne ( float budget_old; float budget_new; string project_number; SqlConnection conn = new SqlConnection =true"); conn.Open(); SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = "SELECT Budget FROM DELETED"; budget_old = (float)Convert.ToDouble(cmd.ExecuteScalar()); cmd.CommandText = "VELG budsjett FRA INSERT"; budget_new = (float)Convert.ToDouble(cmd.ExecuteScalar()); cmd.CommandText = "VELG nummer FRA SLETTET"; project_number = Convert.ToString(cmd.ExecuteScalar()); cmd. CommandText = @"INSERT INTO AuditBudget (@projectNumber, USER_NAME(), GETDATE(), @budgetOld, @budgetNew)"; cmd.Parameters.AddWithValue("@projectNumber", project_number); cmd.Parameters.AddWithValue("@budgetOld ", budget_old); cmd.Parameters.AddWithValue("@budgetNew", budget_new); cmd.ExecuteNonQuery(); ) ) )

Microsoft.SQLServer.Server-navneområdet inneholder alle klientklassene som et C#-program kan trenge. Klasser SqlTriggerContext Og SqlFunction er medlemmer av dette navneområdet. I tillegg inneholder System.Data.SqlClient-navneområdet SqlConnection- og SqlCommand-klassene, som brukes til å etablere forbindelse og interaksjon mellom klienten og databaseserveren. Forbindelsen opprettes ved hjelp av tilkoblingsstrengen "context connection = true".

Deretter defineres Triggers-klassen, som brukes til å implementere triggere. ModifyBudget()-metoden implementerer en trigger med samme navn. Kontekstforekomsten av SqlTriggerContext-klassen lar en applikasjon få tilgang til den virtuelle tabellen som opprettes når triggeren kjøres. Denne tabellen lagrer dataene som fikk utløseren til å utløses. IsUpdatedColumn()-metoden til SqlTriggerContext-klassen lar deg finne ut om den angitte tabellkolonnen er oppdatert.

Dette programmet inneholder to andre viktige klasser: SqlConnection og SqlCommand. En forekomst av SqlConnection-klassen brukes vanligvis til å etablere en tilkobling til en database, og en forekomst av SqlCommand-klassen lar deg utføre SQL-setninger.

Dette eksempelprogrammet kan kompileres ved hjelp av csc-kompilatoren, som er innebygd i Visual Studio. Det neste trinnet er å legge til en referanse til den kompilerte sammenstillingen i databasen:

BRUK SampleDb; GÅ OPPRETT FORSAMLING CLRStoredProcedures FRA "D:\Projects\CLRStoredProcedures\bin\Debug\CLRStoredProcedures.dll" MED PERMISSION_SET = SAFE

CREATE ASSEMBLY-setningen tar administrert kode som input og oppretter et tilsvarende objekt for å lage en CLR-utløser. WITH PERMISSION_SET-leddet i eksemplet spesifiserer at tilgangstillatelser er satt til SAFE.

Til slutt, i eksemplet nedenfor, opprettes et trigger_modify_budget ved å bruke CREATE TRIGGER-setningen:

BRUK SampleDb; GÅ OPPRETT TRIGGER trigger_modify_budget PÅ prosjektet ETTER OPPDATERING SOM EKSTERNT NAVN CLRStoredProcedures.Triggers.ModifyBudget

CREATE TRIGGER-instruksjonen i eksemplet skiller seg fra den samme instruksjonen i de foregående eksemplene ved at den inneholder EXTERNAL NAME parameter. Dette alternativet spesifiserer at koden genereres av fellesspråkets kjøretid. Navnet i denne parameteren består av tre deler. Den første delen spesifiserer navnet på den tilsvarende sammenstillingen (CLRStoredProcedures), den andre spesifiserer navnet på den offentlige klassen definert i eksemplet ovenfor (Triggers), og den tredje spesifiserer navnet på metoden som er definert i denne klassen (ModifyBudget).

avtrekker:

<Определение_триггера>::= (OPPRETT | ENDRE) TRIGGER utløsernavn PÅ (tabellnavn | visningsnavn) ( ( ( FOR | ETTER | I STEDET FOR ) ( [ SLETT] [,] [ INSERT] [,] [ OPPDATERING] ) [ MED TILLEGG ] [ IKKE FOR REPLICATION ] AS sql_statement[...n] ) | ( (FOR | ETTER | I STEDET FOR ) ( [,] ) [ WITH APPEND] [ NOT FOR REPLICATION] AS ( IF UPDATE(column_name) [ (OG | OR) UPDATE( column_name)] [...n] | IF (COLUMNS_UPDATES() (prosess_bit_operator) change_bit_mask) (comparison_bit_operator) bit_mask [...n]) sql_operator [...n] ) )

En trigger kan bare opprettes i den gjeldende databasen, men det er mulig å få tilgang til andre databaser innenfor triggeren, inkludert de som ligger på en ekstern server.

La oss se på formålet med argumentene fra CREATE | ENDRE TRIGGER.

Utløsernavnet må være unikt i databasen. I tillegg kan du spesifisere eierens navn.

Når du spesifiserer WITH ENCRYPTION-argumentet, krypterer serveren utløserkoden slik at ingen, inkludert en administrator, kan få tilgang til eller lese den. Kryptering brukes ofte for å skjule proprietære databehandlingsalgoritmer som er programmererens intellektuelle eiendom eller en forretningshemmelighet.

Triggertyper

Det er to alternativer i SQL Server som bestemmer oppførselen til utløsere:

  • ETTER. Utløseren utføres etter at kommandoene som kalte den er fullført. Hvis kommandoene av en eller annen grunn ikke kan fullføres, blir ikke utløseren utført. Det skal bemerkes at dataendringer som følge av utførelse av en brukerforespørsel og utløserutførelse utføres i kroppen til én transaksjon: hvis utløseren rulles tilbake, vil brukerendringer også bli avvist. Du kan definere flere ETTER-utløsere for hver operasjon (INSERT, UPDATE, DELETE). Hvis du har flere AFTER-utløsere på en tabell, kan du bruke sp_settriggerorder-systemets lagrede prosedyre for å spesifisere hvilken utløser som skal kjøre først og hvilken som kjører sist. Som standard, i SQL Server, er alle utløsere ETTER-utløsere.
  • I STEDET FOR . Utløseren kalles i stedet for å utføre kommandoer. I motsetning til ETTER-utløseren, kan INSTEAD OF-utløseren defineres for både en tabell og en visning. For hver INSERT, UPDATE, DELETE-operasjon kan bare én ISTEDEN FOR-utløser defineres.

Triggere kjennetegnes av typen kommandoer de reagerer på.

Det er tre typer triggere:

  • INSERT TRIGGER – Utløses når det gjøres et forsøk på å sette inn data ved hjelp av INSERT-kommandoen.
  • UPDATE TRIGGER – utløses når det gjøres et forsøk på å endre data ved hjelp av UPDATE-kommandoen.
  • DELETE TRIGGER – utløses når det gjøres et forsøk på å slette data ved hjelp av DELETE-kommandoen.

Konstruksjoner [ SLETT] [,] [ SETT INN] [,] [ OPPDATERING] Og FOR | ETTER | I STEDET FOR ) ([,] bestemme hvilken kommando utløseren vil svare på. Når du oppretter den, må minst én kommando spesifiseres. Tillatt lage en trigger, svarer på to eller alle tre kommandoene.

MED APPEND lar deg lage flere triggere av hver type.

lage en trigger med IKKE FOR REPLIKASJON-argumentet, er det forbudt å kjøre mens tabeller blir modifisert av replikeringsmekanismer.

AS sql_operator[...n]-konstruksjonen definerer et sett med SQL-setninger og kommandoer som vil bli utført når triggeren startes.

Merk at en rekke operasjoner ikke er tillatt inne i en utløser, for eksempel:

  • opprette, endre og slette en database;
  • gjenopprette en sikkerhetskopi av database eller transaksjonslogg.

Disse kommandoene har ikke lov til å utføres fordi de ikke kan rulles tilbake hvis transaksjonen der utløseren ble utført, rulles tilbake. Dette forbudet vil neppe på noen måte påvirke funksjonaliteten til opprettede utløsere. Det er vanskelig å finne en situasjon der du for eksempel, etter å ha endret en tabellrad, må gjenopprette en sikkerhetskopi av transaksjonsloggen.

Trigger programmering

Når du utfører kommandoer for å legge til, endre og slette poster, oppretter serveren to spesielle tabeller: satt inn Og slettet. De inneholder lister over rader som vil bli satt inn eller slettet når transaksjonen er fullført. Strukturen til de innsatte og slettede tabellene er identisk med strukturen til tabellene som utløseren er definert for. Hver utløser oppretter sitt eget sett med innsatte og slettede tabeller, slik at ingen andre utløsere har tilgang til dem. Avhengig av typen operasjon som fikk utløseren til å utføre, kan innholdet i de innsatte og slettede tabellene være forskjellig:

  • INSERT kommando – den innsatte tabellen inneholder alle radene som brukeren prøver å sette inn i tabellen; det vil ikke være en eneste rad i den slettede tabellen; etter at utløseren er fullført, vil alle rader fra den innsatte tabellen flyttes til kildetabellen;
  • DELETE kommando – den slettede tabellen vil inneholde alle rader som brukeren prøver å slette; utløseren kan sjekke hver rad og bestemme om den er tillatt å slettes; det vil ikke være noen rader i den innsatte tabellen;
  • UPDATE-kommando - når den utføres, inneholder den slettede tabellen gamle radverdier som vil bli slettet ved vellykket fullføring

Trigger (database)

Avtrekker(Engelsk) avtrekker) er en spesiell type lagret prosedyre som ikke kalles direkte av brukeren, men hvis utførelse er betinget av en datamodifikasjonshandling: legge til en INSERT, slette en DELETE-rad i en gitt tabell, eller endre OPPDATERING av data i en spesifikk kolonne i en gitt tabell i en relasjonsdatabase. Triggere brukes til å sikre dataintegritet og implementere kompleks forretningslogikk. Utløseren utløses automatisk av serveren når det gjøres forsøk på å endre data i tabellen den er knyttet til. Alle dataendringer den foretar anses å være utført i transaksjonen der handlingen som fikk utløseren til å utløse ble utført. Følgelig, hvis en feil oppdages eller dataintegriteten krenkes, kan denne transaksjonen tilbakeføres.

Når en utløser utløses, bestemmes ved hjelp av nøkkelordene FØR (utløseren kjører før hendelsen knyttet til den utføres; for eksempel før du legger til en post) eller ETTER (etter hendelsen). Hvis utløseren kalles før hendelsen, kan den gjøre endringer i posten som er endret av hendelsen (selvfølgelig, forutsatt at hendelsen ikke sletter posten). Noen DBMS-er pålegger begrensninger for operatørene som kan brukes i en trigger (det kan for eksempel være forbudt å gjøre endringer i tabellen som utløseren henger på osv.)

I tillegg kan utløsere ikke være bundet til en tabell, men til en visning (VIEW). I dette tilfellet, med deres hjelp, implementeres mekanismen "oppdaterbar visning". I dette tilfellet påvirker FØR- og ETTER-nøkkelordene bare rekkefølgen som utløsere kalles i, siden den faktiske hendelsen (slett, sett inn eller oppdater) ikke forekommer.

På noen servere kan det hende at utløsere ikke kalles for hver endrede post, men bare én gang per tabellendring. Slike triggere kalles tabelltriggere.

Eksempel (Oracle):

/* Tabellnivåutløser */ LAG ELLER ERSTATT TRIGGER DistriktOppdatertTrigger ETTER OPPDATERING PÅ distriktet BEGYNN INN INN I infoVERDIER ( "tabell "distrikt" er endret") ; SLUTT ;

I dette tilfellet, for å skille tabellutløsere fra radutløsere, introduseres ytterligere søkeord når radutløsere beskrives. I Oracle er dette FOR HVER RAD.

/* Utløser på radnivå */ OPPRETT ELLER ERSTATT TRIGGER DistriktOppdatertTrigger ETTER OPPDATERING PÅ distrikt FOR HVER RAD BEGYNN INN INN I infoVERDIER ( "én streng i tabellen "distrikt" er endret") ; SLUTT ;


Wikimedia Foundation. 2010.

  • Husstand
  • Spektroskopi

Se hva "Trigger (database)" er i andre ordbøker:

    Vis (database)– Dette begrepet har andre betydninger, se Presentasjon. View (engelsk visning, mer konsonant med det ikke-standardiserte navnet "view", i programmererslang blir det ofte brukt som et lån fra det engelske "view", "view")... ... Wikipedia

    Hierarkiske databaser- En hierarkisk databasemodell består av objekter med pekere fra overordnede objekter til barn, som kobler relatert informasjon sammen. Hierarkiske databaser kan representeres som et tre som består av objekter på forskjellige nivåer.... ... Wikipedia

    Relasjonelle databaser– Relasjonsdatabase er en database basert på en relasjonsdatamodell. Ordet "relasjonell" kommer fra engelsk. forhold. For å jobbe med relasjonsdatabaser brukes relasjons-DBMS. Bruken av relasjonsdatabaser var... ... Wikipedia

    Indeks (databaser)– Dette begrepet har andre betydninger, se Index. Indeks er et databaseobjekt laget for å forbedre ytelsen til datainnhenting. Tabeller i en database kan ha et stort antall rader, som er lagret i ... Wikipedia

    Markør (database)- Dette begrepet har andre betydninger, se Markør (betydninger). Markøren er en lenke til det kontekstuelle minneområdet [kilde ikke spesifisert 126 dager]. I noen implementeringer av informasjonslogiske språket SQL (Oracle, ... ... Wikipedia

    Trigger (verdier)- Trigger (engelsk trigger i betydningen av substantivet "pawl, latch, trigger i generell forstand, et element som setter noe i handling"; i betydningen av verbet "å bringe til handling"): på russisk, opprinnelig en begrep fra feltet ... ... Wikipedia

    Refaktorering av database- (English database refactoring) er en enkel endring i databaseskjemaet som bidrar til å forbedre utformingen samtidig som funksjonell og informativ semantikk opprettholdes. Med andre ord, konsekvensen av databaserefaktorering kan ikke være... ... Wikipedia

    Database- "DB"-forespørselen omdirigeres hit; se også andre betydninger. En database presentert i objektiv form er en samling uavhengig materiale (artikler, beregninger, forskrifter, rettsavgjørelser og annet lignende materiale), ... ... Wikipedia

    Databasedesign- prosessen med å lage et databaseskjema og definere nødvendige integritetsbegrensninger. Innhold 1 Hovedoppgaver innen databasedesign ... Wikipedia

    Datamodell- I klassisk databaseteori er en datamodell en formell teori for å representere og behandle data i et databasestyringssystem (DBMS), som inkluderer minst tre aspekter: 1) strukturaspektet: metoder for å beskrive typer og ... .. Wikipedia