Skriva sql -triggers. Funktioner hos industriella servrar


Anpassad från en artikel av Robert Marda på sqlservercentral.com: Auditing Through Triggers

I den här artikeln ger Robert exempel på kod för flera triggers installerade på tabeller för att granska användaråtgärder med MS SQL Server 7.0 / 2000 -poster.

För en förklaring av hur triggers fungerar i allmänhet och hur de fungerar i SQL Server 7.0 och SQL Server 2000 kan du hänvisa till följande artiklar av Brian Kelley:

Den första artikeln förklarar syftet med speciella tabeller för infogning och radering (infogade och borttagna tabeller).
Exemplen nedan fungerar på SQL Server 2000, men de har bara testats på SQL Server 7.0.
Först måste vi skapa de tabeller som är nödvändiga för vidare arbete. Kör skriptet nedan i Query Analyzer:

SKAPA BORD (
IDENTITET (1, 1) INTE NULL,




NULL,
(35) NULL
) PÅ

SKAPA BORD (
INTE NULL,
(25) NULL,
(25) NULL,
(75) NULL,
(50) NULL,
NULL,
(35) NULL,
) PÅ

Utlösare som övervakar radering

Om du vill ta bort från en tabell kan du använda en exempelutlösare som infogar en rad i ComponentsDeleted när en rad tas bort från tabellen.

Komponenter: SKAPA TRIGGER raderad av ON dbo.Components
FÖR RADERING
SOM
INSERT INTO ComponentsDeleted (Iden, ComponentName, SerialNumber,
Kommentarer,
Användarnamn, DeletedDate, DeletedBy)
VÄLJ Iden, Komponentnamn, Serienummer, Kommentarer, Användarnamn, getdate (),
SYSTEM_USER
FRÅN raderad

Ta bort en eller två rader från tabellen Komponenter. Titta nu på tabellen ComponentsDeleted så ser du raderna som du raderade med datum och tid när de raderades.

Att installera ett enkelt granskningssystem som använder utlösare, exempel på vilka presenteras i den här artikeln, kan vara användbart när du behöver veta vem och när du utförde åtgärderna som övervakas av utlösare i din databas.

UtlösareÄr en underrutin, liknande en databasprocedur, automatiskt uppringd av DBMS när en post ändras, tas bort eller läggs till i en tabell. Utlösare kan inte nås från programmet, överföra parametrar till dem eller ta emot resultat från dem. Triggers används oftast för att upprätthålla referensintegritet och kaskaddatabasoperationer. Referensspecifikationer som definierar stegvisa raderingar och uppdateringsåtgärder och skapas när tabeller deklareras implementeras också via triggers, men texten för dessa triggers redigeras inte.

Tilldela triggers

Förhindra ändringar (till exempel förhindra att fakturor ändras efter att de har skickats ut).
... Loggförändringar (till exempel behålla kopior av gammal data).
... Granskning av ändringar (till exempel loggning av användare och roller som är involverade i ändringar).
... Genomföra ändringar (till exempel se till att alla ändringar dateras av serverklockan, inte klientklockan).
... Genomförande av affärsregler.
... Replikering av data (till exempel, registrera alla ändringar som kommer att skickas till en annan databas vid en senare version).
... Prestandaförbättringar (till exempel uppdatering av saldot efter varje transaktionsdetalj för att påskynda frågor).

Förklarar utlösare

SKAPA TRIGGER {FÖRE | EFTER} {RADERA | INSERT | UPDATE [AV ]} Hänvisning {GAMMAL {[RAD]|TABELL [SOM] } NY {RAD | TABELL} [SOM] }] [FÖR VARJE {UTGIFT | RAD [NÄR ]}]
[BÖRJA ATOMISKT]

[SLUTET]

Nyckelord

. FÖRE | EFTER- utlös starttid - före | efter uppdateringen.
. RADERA | INSERT | UPDATE= utlösarhändelse.
. FÖR VARJE RAD- för varje rad (radutlösare, sedan NÄR).
. FÖR VARJE UTTALANDE- för hela laget (som standard).
. Hänvisning- låter dig tilldela upp till 4 alias till gamla och. eller nya rader och | eller tabeller som kan nås av utlösare.

Utlösningsbegränsningar

Utlösaren kan inte innehålla operatörer:
... Definition, radering och modifiering av databasobjekt (tabeller, domäner, etc.)
... Transaktionsbehandling (COMMIT, ROLLBACK)
... Anslutningar och frånkopplingar till databasen (CONNECT, DISCONNECT)

Applikationsfunktioner
... Utlösaren körs efter att alla andra (deklarativa) integritetskontroller har tillämpats och är användbara när testkriteriet är tillräckligt komplext. Om deklarativa kontroller avvisar uppdateringsoperationen kommer den inte till punkten att utföra triggers. Utlösaren fungerar i samband med en transaktion, men FK -begränsningen inte.
... Om en utlösare orsakar ytterligare modifiering av basbordet, leder det oftast inte till dess rekursiva körning, men detta bör klargöras. SQL Server 2005 ger möjlighet att ange rekursion upp till 255 nivåer med hjälp av alternativet ALTERNATIV (MAXRECURSIV 3).
... Utlösare misslyckas vanligtvis vid behandling av binära stora kolumner (BLOB).
... Det bör komma ihåg att varje gång data uppdateras skapar DBMS automatiskt de så kallade trigger virtuella tabellerna som har olika namn i olika DBMS. I InterBase och Oracle - Dessa är nya och gamla. I SQL Server, Infogad och borttagen. När data ändras skapas dessutom båda. Dessa tabeller har samma antal kolumner, med samma namn och domäner, som tabellen uppdateras. SQL Server 2005 ger möjlighet att ange en tabell, inklusive en tillfällig tabell, i vilken data ska infogas med hjälp av OUTPUT Inserted.ID,… INTO @ nyckelordet.
... I ett antal DBMS är det tillåtet att deklarera utlösare för flera åtgärder samtidigt. För att implementera olika reaktioner på olika åtgärder tillhandahåller Oracle predikaten Deleting, Inserting, Updating, som returnerar True för motsvarande typ av uppdatering.
... I Oracle kan du ange en lista med kolumner (efter uppdatering av) för uppdateringsutlösare, vilket säkerställer att utlösaren endast anropas när värdena för endast de kolumnerna ändras.
... För varje utlösarhändelse kan flera utlösare deklareras (i Oracle, 12 utlösare per tabell) och vanligtvis bestäms ordningen som de avfyras av i vilken ordning de skapas. I vissa DBMS, till exempel InterBase, anges startorder med det extra nyckelordet POSITION. I allmänhet antas att triggers bör köras för varje kommando först och sedan för varje rad.
... Utlösare kan vara inbäddade i varandra. Till exempel tillåter SQL Server 32 kapslingsnivåer (med @@ NextLevel global variabel kan du bestämma kapslingsnivån).

Nackdelar med triggers

Komplexitet. Att placera vissa åtgärder på data i en databas komplicerar dess design, implementering och administration.
... Diskretion av funktionalitet från användaren. Det är svårt att uppgradera ett program när vissa funktioner är dolda.
... Påverkan på prestanda. Med ett litet antal triggers ökar behandlingstiden.

Ändra och ta bort triggers

Om du vill släppa en trigger använder du DROP TRIGGER -satsen
... För att ändra en utlösare, använd ALTER TRIGGER ... -uttalandet.
... Inaktivera triggers
I vissa fall, till exempel vid batch -laddning, måste triggers inaktiveras. Ett antal DBMS ger motsvarande funktioner. I Oracle och SQL Server är sökorden DISABLE | ENABLE, i InterBase INACTIVE | ACTIVE i ALTER TRIGGER -satsen.

Funktioner hos industriella servrar

1) InterBase / Firebird

SKAPA TRIGGER FÖR {AKTIV | INAKTIV} {FÖRE | EFTER} {INSERT | DELETE | UPDATE} [PLACERA ]
SOM [DEKLARERAR VARIABEL [()]]
BÖRJA

SLUTET

Exempel:

SKAPA TRIGGER BF_Del_Cust FÖR Kund
AKTIV INNAN RADERING AV STÄLLNING 1 AS
BÖRJA
DELETE OF ORDER WHERE Orders.CNum = Customer.CNum;
SLUTET;

2) SQL Server

SKAPA TRIGGER [MED KRITERING] {FÖR | EFTER | INSTEAD OF} {INSERT | UPDATE | DELETE}
SOM

ANVÄNDNING B1;

SKAPA TRIGGER InUpCust1 PÅ KUNDEN EFTER INSÄTT, UPPDATERING
AS RAISEERROR ("Ändrad kundtabell");

Ytterligare typer av triggers

Oracle och SQL Server har möjlighet att skapa (ersättnings) triggers för icke-uppdaterbara vyer. För detta tillhandahålls INSTEAD OF keyword:

SKAPA TRIGGER PÅ INSTEAD OF INSERT AS ...

Du kan spåra klientens försök att uppdatera data med hjälp av vyer och utföra vissa åtgärder, bearbeta icke-uppdaterbara vyer och så vidare.
... SQL Server DBMS tillhandahåller en rollback -trigger som faktiskt stoppar alla åtgärder med utfärdande av ett meddelande:

ROLLBACK TRIGGER

utlösare:

<Определение_триггера>:: = (SKAPA | ALTER) TRIGGER trigger_name ON (tabellnamn | view_name) (((FOR | EFTER | INSTEAD OF) ([DELETE] [,] [INSERT] [,] [UPDATE]) [MED APPEND] [INTE FÖR REPLIKATION] SOM sql_operator [... n]) | ((FOR | EFTER | INSTEAD OF) ([,]) [MED APPEND] [NOT FOR REPLICATION] AS (OM UPDATE (column_name) [(AND | OR) UPDATE ( column_name)] [... n] | IF (COLUMNS_UPDATES () (processing_bit_operator) change_mask_bit) (jämförelse_bit_operator) mask_bit [... n]) sql_operator [... n]))

En utlösare kan bara skapas i den aktuella databasen, men det är tillåtet att komma åt andra databaser inuti utlösaren, inklusive de som finns på en fjärrserver.

Tänk på att tilldela argument från CREATE | ALTER TRIGGER.

Utlösarnamnet måste vara unikt i databasen. Alternativt kan du ange namnet på ägaren.

Med argumentet MED ENKRYPTION krypterar servern utlösarkoden så att ingen, inklusive administratören, kan komma åt eller läsa den. Kryptering används ofta för att dölja upphovsrättsdatabehandlingsalgoritmer som är programmerarens immateriella egendom eller affärshemligheter.

Utlösartyper

Det finns två parametrar i SQL Server som definierar triggers beteende:

  • EFTER. Utlösaren körs efter framgångsrik körning av kommandona som kallade den. Om kommandona av någon anledning inte kan slutföras framgångsrikt, utförs inte utlösaren. Det bör noteras att dataändringar som en följd av en användarförfrågan och triggkörning utförs i en transaktion: om utlösaren rullar tillbaka, kommer användarändringar också att avvisas. Flera EFTER -utlösare kan definieras för varje operation (INSERT, UPDATE, DELETE). Om en tabell har flera EFTER -utlösare kan du använda sp_settriggerorder -systemets lagrade procedur för att ange vilken som ska köras först och vilken som blir den sista. Som standard i SQL Server är alla utlösare EFTER utlösare.
  • ISTÄLLET FÖR. Utlösaren kallas istället för att utföra kommandon. Till skillnad från AFTER -utlösaren kan INSTEAD OF —trigger definieras både för tabellen och för vyn. För varje INSERT, UPDATE, DELETE operation kan endast en INSTEAD OF trigger definieras.

Utlösare utmärks av typen av kommandon de svarar på.

Det finns tre typer av utlösare:

  • INSERT TRIGGER - Utlöst när du försöker infoga data med INSERT -kommandot.
  • UPDATE TRIGGER - Avfyras när ett försök görs att ändra data med UPDATE -kommandot.
  • DELETE TRIGGER - Avfyras när du försöker radera data med kommandot DELETE.

Konstruktioner [DELETE] [,] [INSERT] [,] [UPDATE] och FÖR | EFTER | ISTÄLLET FÖR) ([,] avgöra vilket kommando utlösaren svarar på. Minst ett kommando måste anges när du skapar det. Tillåten utlösa skapande svara på två eller alla tre kommandon.

Med WITH APPEND -argumentet kan du skapa flera triggers av varje typ.

skapa en utlösare med argumentet NOT FOR REPLICATION förhindras det att köras medan replikeringsmotorer uppdaterar tabeller.

AS -konstruktionen sql_operator [... n] definierar en uppsättning SQL -satser och kommandon som körs när utlösaren körs.

Observera att ett antal operationer inte är tillåtna i en utlösare, till exempel:

  • skapa, ändra och ta bort en databas;
  • återställa en databas eller transaktionsloggbackup.

Dessa kommandon får inte köras eftersom de inte kan rullas tillbaka om transaktionen som utlösaren körs rullas tillbaka. Detta förbud kan knappast på något sätt påverka funktionaliteten hos de skapade triggarna. Det är svårt att hitta en situation där du, till exempel, efter att ha ändrat en rad i en tabell, måste återställa en transaktionsloggbackup.

Utlösarprogrammering

När du kör kommandon för att lägga till, ändra och ta bort poster skapar servern två speciella tabeller: infogad och raderade... De innehåller listor över rader som kommer att infogas eller tas bort i slutet av transaktionen. Strukturen för de infogade och borttagna tabellerna är identisk med strukturen för de tabeller för vilka utlösaren är definierad. Varje utlösare skapar sin egen uppsättning infogade och borttagna tabeller, så ingen annan utlösare kan komma åt dem. Beroende på vilken typ av operation som orsakade utlösaren att utföra, kan innehållet i de infogade och borttagna tabellerna vara olika:

  • INSERT -kommando - Den infogade tabellen innehåller alla rader som användaren försöker infoga i tabellen. det kommer inte att finnas några rader i den borttagna tabellen; när utlösaren är klar flyttas alla rader från den infogade tabellen till den ursprungliga tabellen.
  • DELETE kommando - den borttagna tabellen innehåller alla rader som användaren kommer att försöka ta bort; utlösaren kan kontrollera varje rad och avgöra om den får raderas; det kommer inte att finnas några rader i den infogade tabellen;
  • UPDATE -kommando - när den tas bort innehåller den borttagna tabellen gamla radvärden som kommer att raderas vid framgång

Det är mycket möjligt att du vet vad en databasutlösare är, åtminstone i allmänna termer. Det finns till och med en chans att du vet att MySQL stöder triggers och är bekant med dem. Men chansen är att de flesta av er, till och med beväpnade med kunskap, inte har en aning om vilka fördelar MySQL -triggers döljer. Du bör ha det här verktyget i din arsenal, eftersom triggers helt kan förändra ditt sätt att arbeta med data.

Introduktion : vad är en utlösare

"I takt med att applikationer blir mer och mer komplexa kan vi abstrakta applikationsskiktet för att hantera dem och öka användbarheten i utvecklingsprocessen."

För dem som inte vet är en trigger en regel som du lägger in i en tabell, och när du kör en DELETE, UPDATE eller INSERT utför den ytterligare åtgärder. Till exempel kan vi registrera en ändring i loggen. Men i stället för att skriva två separata frågor (en för att ändra data, den andra för att skriva till loggen) kan du skriva en utlösare som innehåller regeln: ”När en rad ändras, skapa en ny rad i en annan tabell för att rapportera vad som har gjort. ändringar ”. Detta tillvägagångssätt skapar viss redundans i huvudfrågan, men nu går det inte två olika paket till din databaseserver för att göra två olika saker, vilket i allmänhet förbättrar prestanda.

Utlösare har introducerats i MySQL sedan version 5.0.2. Utlösarsyntaxen är något främmande. MySQL använder ANSI SQL: 2003 -standarden för procedurer och andra funktioner. Om du arbetar med programmeringsspråk blir det inte svårt att förstå det. Specifikationen är inte allmänt tillgänglig, så vi kommer att försöka använda enkla strukturer och förklara vad som händer i utlösaren. Samma strukturer kommer att användas som i alla programmeringsspråk.

Som nämnts ovan körs utlösare som procedurer på UPDATE, DELETE och INSERT -händelser. De kan utföras antingen före eller efter att händelsen har definierats. På så sätt kan du definiera en utlösare som ska köras före DELETE eller efter DELETE, och så vidare. Detta innebär att du kan ha en utlösare som kommer att köras före INSERT och en helt annan som kommer att köras efter INSERT, vilket är ett mycket kraftfullt verktyg.

Komma igång: bordstruktur, verktyg och anteckningar

I den här artikeln kommer vi att arbeta med ett fiktivt system för en kundvagn, vars produkt har ett pris. Datastrukturen kommer att vara så enkel som möjligt för att demonstrera procedurerna för att arbeta med triggers. Namnen på tabeller och kolumner är utformade för att vara lättare att förstå, inte för verkligt arbete. TIMESTAMPS används också för att underlätta inlärningsprocessen. Tabellerna heter carts, cart_items, cart_log, items, items_cost.

Mycket enkla frågor kommer också att användas. Det finns ingen koppling mellan variabler och ingen datainmatning används. Frågorna var beredda att vara så enkla och läsbara som möjligt.

Particle Tree PHP Quick Profiler användes för att bestämma körtiden. Gräslök användes för att illustrera effekterna på databasen. Gräslök är endast för MySQL 5+ och liknar mycket PHPMyAdmin. Det har ett mer uttrycksfullt gränssnitt, men innehåller betydligt fler buggar för tillfället. Användningen av Chive drivs av önskan att presentera mer uttrycksfulla skärmdumpar av förfrågningar.

Du kan också behöva ändra MySQL -avgränsaren när du skapar triggers. Den ursprungliga MySQL -avgränsaren är; , men eftersom vi kommer att använda en avgränsare för de tillagda frågorna kan det vara nödvändigt att uttryckligen ange avgränsaren för att skapa frågor från kommandoraden. När du använder gräslök behöver du inte byta separator.

För att ändra avgränsaren måste du köra kommandot före utlösarkommandot:

DELIMITER $$

Och efter utlösarkommandot måste du ange:

DELIMITER;

Enkel utlösare: dataintegritet

Om du vill utföra en mindre normalisering av databasstrukturen kan det visa sig att du kommer att behöva ta bort huvuddatakällan som har fragment som deltar i det allmänna dataflödet. Till exempel kan du ha en cart_id som refererar till två eller tre tabeller utan främmande nycklar, särskilt när du använder MyISAM -motorn som inte stöder dem.

I ett sådant fall kan du ha utfört följande operationer tidigare:

$ sql = "DELETE FROM no_trigger_cart_items WHERE cart_id = 1";
$ rs = $ this-> db-> fråga ($ sql);
$ sql = "DELETE FROM no_trigger_carts WHERE cart_id = 1";
$ rs = $ this-> db-> fråga ($ sql);

Beroende på hur organiserad du är kan du ha ett API eller en metod som tömmer dina papperskorgar. Om detta är ditt fall har du en isolerad funktion som utför två förfrågningar. Om självorganisation inte är din starka sida, måste du alltid komma ihåg att tömma korgen när du tar bort en specifik korg. Inte svårt, men om du glömmer förlorar du dataintegritet.

Låt oss gå tillbaka till triggers. Låt oss skapa en enkel utlösare som, när en vagn tas bort, kommer att ta bort alla vagnartiklar som har samma cart_id:

SKAPA TRIGGER `handledning`.` Före_deleter_vagnar`
INNAN DU RADERAR PÅ `trigger_carts` FÖR VARJE RAD
BÖRJA
DELETE FROM trigger_cart_items WHERE OLD.cart_id = cart_id;
SLUTET

Mycket enkel syntax. Låt oss titta närmare på avtryckaren.

Den första raden är "SKAPA TRIGGER` handledning`.`before_delete_carts`". Detta är MySQL -kommandot för att skapa en databasutlösare "tutorial" med namnet "before_delete_carts". Vi kommer att använda namngivningsschemat för när_What_Table -utlösarna.

Den andra raden specificerar för MySQL definitionen av "FÖRE DELETE ON" trigger_carts` FOR EACH ROW "-utlösaren. Vi säger åt MySQL att göra något för varje rad innan vi tar bort från en given tabell. Vad man ska göra förklaras vidare mellan BEGIN och END. "DELETE FROM trigger_cart_items WHERE OLD.cart_id = cart_id;" För MySQL är det specificerat att innan du tar bort från trigger_carts måste du ta OLD.cart_id och även ta bort från trigger_cart_items. GAMLA syntaxen definierar en variabel. Det kommer att diskuteras i nästa avsnitt där gammalt och nytt kombineras.

Fördelen med att använda en trigger är att integriteten för dina data flyttas från det logiska lagret till datalagret, där det ska vara. Det finns också en viss ökning av systemets prestanda.

Två frågor:

En fråga med trigger:

Som du kan se är det en liten prestationsökning som kan förväntas. Exempeldatabasen använder samma server som klienten. Men om databasservern ligger på en annan plats, bör du förvänta dig en större skillnad, eftersom tidpunkten för överföring av data mellan servrar kommer att läggas till utförandetiden för frågor. Det bör också noteras att första gången utlösaren kan köras betydligt långsammare än nästa gång.

Att flytta datalogik till datalagret liknar att flytta stylingen från markeringslagret till presentationslagret, som i hela världen är känt som CSS.

Underbar enkel utlösare: loggning och granskning

Nästa exempel vi kommer att titta på är relaterat till händelseloggning. Till exempel vill vi övervaka varje objekt som läggs i vagnen. Vi kanske vill spåra köpbetyg för artiklar. Kanske vill vi bara ha en kopia av varje artikel i vagnen, inte nödvändigtvis för försäljning, utan för att analysera kundbeteende. Oavsett anledning, låt oss ta en titt på INSERT -utlösaren, vilket öppnar möjligheter för loggning eller granskning av våra data.

Innan vi använde avtryckaren gjorde vi förmodligen något liknande:

Vi kan nu skapa en mycket enkel utlösare för loggningsprocessen:

SKAPA TRIGGER `after_insert_cart_items`
EFTER INSERT PÅ `trigger_cart_items` FÖR VARJE RAD
BÖRJA
INSERT INTO trigger_cart_log (cart_id, item_id)
VÄRDEN (NEW.cart_id, NEW.item_id);
SLUTET

Den första raden är "SKAPA TRIGGER` efter_insats_vagn_artiklar` ". För MySQL är kommandot inställt för att skapa en utlösare med namnet "after_insert_cart_items". Namnet kan vara "Foo" eller "BullWinkle" eller något annat, men det är bättre att använda det tidigare beskrivna utlösningsnamnschemat. Detta följs av "EFTER INSERT ON` trigger_cart_items` FÖR VARJE RAD". Återigen säger vi att efter att något har infogats i trigger_cart_items måste operationer utföras mellan BEGIN och END för varje rad.

Rad "INSERT INTO trigger_cart_log (cart_id, item_id) VALUES (NEW.cart_id, NEW.item_id);" är en standardfråga med två variabler. Detta använder de NYA värdena som infogas i tabellen cart_items.

Återigen är vår fråga snabbare:

För att kontrollera att utlösaren fungerar, låt oss titta på värdena i tabellen:

Mer komplex utlösare: företagslogik

Från och med nu kommer vi att sluta titta på det gamla sättet att använda flera frågor och jämföra dem med tekniken att använda triggers. Låt oss titta på några mer avancerade exempel på att använda triggers.

Affärslogik är där misstag växer fram. Trots omsorg och uppmärksamhet vid organisation av processen går något alltid fel. En utlösare för UPDATE kan mildra detta lite. Vi har förmågan i utlösaren att beräkna det gamla värdet och ställa in det nya värdet baserat på poängen. Till exempel vill vi alltid ange priset på en produkt med 30% premie till kostnaden. Detta leder till det faktum att när vi ändrar (UPDATE) priset, måste vi ändra (UPDATE) priset. Låt oss använda en trigger.

SKAPA TRIGGER `efter_uppdateringskostnad`
EFTER UPPDATERING PÅ `trigger_items_cost` FÖR VARJE RAD
BÖRJA
UPDATE trigger_items
SET -pris = (NYHET. Kostnad * 1,3)
WHERE item_id = NEW.item_id;
SLUTET

Vi ändrar produktbordet med priser baserade på NEW.cost * 1.3. Om du anger ett värde på $ 50 bör priset vara $ 65.

Denna trigger fungerar utmärkt.

Låt oss titta på ett mer komplext exempel. Vi har redan en regel som ändrar priset på en vara baserat på kostnad. Nu vill vi fastställa några nivåer. Om priset är mindre än $ 50 är det verkliga värdet $ 50. Om priset är mer än $ 50, men mindre än $ 100, är ​​det verkliga värdet $ 100.

För att lösa problemet arbetar vi igen med UPDATE, men den här gången kommer triggen att köras innan frågan körs. Ett IF -uttryck kommer också att användas.

Här är utlösartexten:

SKAPA TRIGGER `före_uppdateringskostnad`
FÖRE UPPDATERING PÅ `trigger_items_cost` FÖR VARJE RAD
BÖRJA
OM NY. Kostnad< 50 THEN
SET NEW.cost = 50;
ELSEIF NEW.cost> 50 AND NEW.cost< 100 THEN
SET NEW.cost = 100;
SLUTA OM;
SLUTET

Detta är inte en fråga, utan en överlappning av värden. Om priset är mindre än $ 50, sätt det till $ 50. Om priset ligger mellan $ 50 och $ 100, sätt det till $ 100. Om det är högre, lämnar vi det bara som det är. Syntaxen skiljer sig inte från andra språk på serversidan. Du måste stänga IF -uttalandet med END IF.

Låt oss kontrollera arbetet med vår utlösare. Om du anger ett värde på $ 30 bör priset vara $ 50:

För ett värde av $ 85:

För att kontrollera att AFTER UPDATE -utlösaren fortfarande fungerar bör priset vara $ 130:

Slutsats

I den här artikeln har vi bara vidrört isberget av triggers i MySQL. De låter dig överföra regler för att arbeta med data från programlogiknivån till datanivån.
Kanske att använda triggers på en sida är en krångel som tar tid och ansträngning. Men komplexa webbapplikationer kan helt transformeras med hjälp av triggers.

163

Föregående syntax gäller endast DML -triggers. DDL -utlösare har en något annan form av syntax som kommer att visas senare.

Här anger schema_name -parametern namnet på schemat som utlösaren tillhör, och parameteren trigger_name anger namnet på utlösaren. Parametern tabellnamn anger namnet på tabellen som utlösaren skapas för. (Utlösare för vyer stöds också, vilket indikeras av parametern view_name.)

Du kan också ställa in utlösartypen med två ytterligare parametrar: EFTER och INSTEAD OF. (FOR -parametern är synonym med AFTER -parametern.) EFTER utlösare kallas efter att åtgärden som utlöser utlösaren har utförts och utlösare som INSTEAD OF körs istället för åtgärden som utlöser utlösaren. EFTER utlösare kan bara skapas på tabeller och INSTEAD OF triggers kan skapas på både tabeller och vyer.

Parametrarna INSERT, UPDATE och DELETE anger åtgärden för utlösaren. Utlösaråtgärd hänvisar till Transact-SQL-satsen som utlöser utlösaren. Varje kombination av dessa tre instruktioner är tillåten. DELETE -satsen är inte tillåten om alternativet IF UPDATE används.

Som du kan se i syntaxen i CREATE TRIGGER -satsen anges triggersåtgärden i AS sql_statement -specifikationen.

Med Database Engine kan du skapa flera utlösare för varje tabell och för varje åtgärd (INSERT, UPDATE och DELETE). Som standard finns det ingen specifik ordningsföljd för flera triggers för en given ändringsåtgärd.

Endast databasens ägare, DDL -administratörer och ägaren till tabellen som utlösaren definieras för får skapa utlösare för den aktuella databasen. (Till skillnad från andra typer av CREATE -behörigheter kan den här behörigheten inte överföras.)

Ändra strukturen på en trigger

Transact-SQL stöder också uttalandet ALTER TRIGGER som ändrar utlösarens struktur. Denna instruktion används vanligtvis för att modifiera en triggers kropp. Alla klausuler och parametrar i ALTER TRIGGER -satsen har samma innebörd som klausulerna och parametrarna i CREATE TRIGGER -satsen med samma namn.

Om du vill ta bort utlösare i den aktuella databasen använder du satsen DROP TRIGGER.

Använda borttagna och infogade virtuella tabeller

När du skapar en utlösaråtgärd måste du vanligtvis ange om det refererar till ett kolumnvärde innan eller efter att det har ändrats av åtgärden som utlöser utlösaren. Av denna anledning används två speciellt namngivna virtuella tabeller för att testa effekten av uttalandet som utlöste utlösaren:

    raderad - innehåller kopior av rader raderade från tabellen;

    infogad - Innehåller kopior av rader infogade i tabellen.

Strukturen för dessa tabeller motsvarar strukturen i tabellen för vilken utlösaren är definierad.

Borttaget bord används när CREATE TRIGGER -satsen anger en DELETE- eller UPDATE -sats, och om satsen anger en INSERT- eller UPDATE -sats, används den bord infogat... Det betyder att en raderad tabell skapas för varje DELETE -sats som körs i trigger -åtgärden. På samma sätt skapas en infogad tabell för varje INSERT som körs i en utlösaråtgärd.

En UPDATE -sats anses vara en DELETE -sats följt av en INSERT -sats. Därför skapas både den raderade tabellen och den infogade tabellen (i den ordningen) för varje UPDATE -sats som körs i utlösaråtgärden.

De infogade och borttagna tabellerna implementeras med radversionering, som diskuterades i föregående artikel. När en DML -sats (INSERT, UPDATE eller DELETE) körs på en tabell med lämpliga triggers skapas alltid radversioner för eventuella ändringar i tabellen. När en utlösare behöver information från den borttagna tabellen kommer den åt data i radversionslagret. När det gäller den infogade tabellen hänvisar utlösaren till de senaste radversionerna.

Radversionsmotorn använder tempdb -systemdatabasen som radversionslagret. Av denna anledning, om databasen innehåller ett stort antal ofta använda triggers, bör du förvänta dig en betydande ökning av storleken på denna systemdatabas.

DML Trigger -applikationer

Dessa triggers används för en mängd olika uppgifter. I det här avsnittet kommer vi att titta på flera användningsområden för DML -utlösare, särskilt efter och i stället för utlösare.

EFTER utlösare

Som du redan vet kallas EFTER utlösare efter att åtgärden som utlöser utlösaren körs. En AFTER -utlösare anges med sökordet AFTER eller FOR. EFTER utlösare kan endast skapas på basbord. Utlösare av denna typ kan användas för att utföra bland annat följande operationer:

    skapa en logg över aktivitetsloggar i databastabeller;

    genomförande av affärsregler;

    genomdriva referensintegritet.

Skapa en logglogg

I SQL Server kan du spåra dataändringar med hjälp av CDC -datainsamlingssystemet. DML -triggers kan också lösa detta problem. Exemplet nedan visar hur du kan använda triggers för att skapa en logg över aktivitetsloggar i databastabeller:

ANVÄND SampleDb; / * AuditBudget -tabellen används som en aktivitetslogg i projekttabellen * / GO CREATE TABLE AuditBudget (ProjectNumber CHAR (4) NULL, UserName CHAR (16) NULL, Date DATETIME NULL, BudgetOld FLOAT NULL, BudgetNew FLOAT NULL); GO CREATE TRIGGER trigger_ModifyBudget ON Project EFTER UPDATE AS OM UPDATE (budget) BEGIN DECLARE @budgetOld FLOAT DECLARE @budgetNy FLOAT DECLARE @projectNumber CHAR (4) VÄLJ @budgetOld = (VÄLJ = Budget FRUDNew raderad) VÄLJ VÄLJ raderad) INSERT INTO AuditBudget VALUES (@projectNumber, USER_NAME (), GETDATE (), @budgetOld, @budgetNew) END

I det här exemplet skapas en AuditBudget -tabell som lagrar alla ändringar i budgetkolumnen i projekttabellen. Ändringar av den här kolumnen kommer att skrivas till den här tabellen via trigger_ModifyBudget -utlösaren.

Denna utlösare aktiveras för varje ändring av budgetkolumnen med ett UPDATE -uttalande. När denna utlösare körs tilldelas värdena för de raderade och infogade tabellraderna motsvarande variabler @budgetOld, @budgetNew och @projectNumber. Dessa tilldelade värden, tillsammans med användarnamnet och aktuellt datum, infogas sedan i AuditBudget -tabellen.

Detta exempel förutsätter att endast en rad kommer att uppdateras åt gången. Därför är detta exempel en förenkling av det allmänna fallet där en trigger hanterar uppdateringar med flera rader. Om du kör följande Transact-SQL-satser:

då kommer innehållet i AuditBudget -tabellen att vara så här:

Genomförande av affärsregler

Utlösare kan användas för att skapa affärsregler för applikationer. Skapandet av en sådan utlösare visas i exemplet nedan:

ANVÄND SampleDb; - Trigger trigger_TotalBudget är ett exempel på användning - en trigger för att implementera en affärsregel GO CREATE TRIGGER trigger_TotalBudget ON Project EFTER UPDATE AS IF UPDATE (Budget) BEGIN DECLARE @ sum_old1 FLOAT DECLARE @ sum_old2 FLOAT DECLARE @sum_news SELECT Budget) sum_old1 = (SELECT SUM (p.Budget) FROM project p WHERE p.Number NOT IN (SELECT d.Number FROM deleted d)) SELECT @ sum_old2 = (SELECT SUM (Budget) FRÅN raderad) IF @sum_new> ( @ sum_old1 + @ sum_old2) * 1.5 BÖRJA UTSKRIFT "Budgeten har inte ändrats" ROLLBACK TRANSACTION END ELSE PRINT "Budgeten har ändrats" END

Här skapar du en regel för att styra ändringen av projektbudgetar. Trigger_TotalBudget -utlösaren kontrollerar varje budgetändring och kör bara UPDATE -uttalanden som ökar summan av alla budgetar med högst 50%. Annars rullas UPDATE -satsen tillbaka med en ROLLBACK TRANSACTION -sats.

Integritetsbegränsning

I databashanteringssystem tillämpas två typer av begränsningar för att säkerställa dataintegritet: deklarativa begränsningar, som definieras med hjälp av CREATE TABLE och ALTER TABLE språkuttalanden; procedurintegritet som begränsas av triggers.

I normala situationer bör deklarativa begränsningar användas för att säkerställa konsekvens, eftersom de stöds av systemet och inte behöver implementeras av användaren. Användning av triggers rekommenderas endast i de fall där det inte finns några deklarativa integritetsbegränsningar.

Exemplet nedan visar upprätthållande av referensintegritet genom utlösare på medarbetarna och Works_on -tabellerna:

ANVÄND SampleDb; GO CREATE TRIGGER trigger_WorksonIntegrity ON Works_on EFTER INSERT, UPDATE AS IF UPDATE (EmpId) BEGIN IF (SELECT Employee.Id FROM Employee, insert WHERE Employee.Id = insert.EmpId) IS NULL BEGIN ROLLBACK TRANSACTION PRINT "rad har inte infogats UTSKRIFT "Linjen infogades / modifierades" SLUT

Trigger_WorksonIntegrity -utlösaren i det här exemplet kontrollerar referensintegriteten för medarbetarna och Works_on -tabellerna. Detta innebär att varje ändring av ID -kolumnen i den refererade tabellen Works_on kontrolleras, och varje kränkning av denna begränsning är inte tillåten. (Detsamma gäller när du sätter in nya värden i kolumnen Id.) ROLLBACK TRANSACTION -satsen i det andra BEGIN -blocket rullar tillbaka INSERT- eller UPDATE -satsen om en referensintegritetsbegränsning bryts.

I det här exemplet kontrollerar utlösaren de första och andra referensintegritetsproblemen mellan medarbetarna och Works_on -tabellerna. Och exemplet nedan visar en utlösare som söker efter referensintegritetsproblem i det tredje och fjärde fallet mellan samma tabeller (dessa fall diskuterades i artikeln "Transact -SQL - Skapa tabeller"):

ANVÄND SampleDb; GO CREATE TRIGGER trigger_RefintWorkson2 ON Employee EFTER DELETE, UPDATE AS IF UPDATE (Id) BEGIN IF (SELECT COUNT (*) FROM Works_on, delete WHERE Works_on.EmpId = delete.Id)> 0 BEGIN RACKBACK TRANSACTION PRINT "/ Raden infogades inte "END ELSE PRINT" En rad infogades / modifierades "END

I stället för utlösare

Utlösare med förslag ISTÄLLET FÖR ersätter motsvarande åtgärd som utlöste det. Denna utlösare körs efter att motsvarande infogade och raderade tabeller har skapats, men innan integritetskontroller eller någon annan åtgärd utförs.

INSTEAD OF triggers kan skapas för både tabeller och vyer. När en Transact-SQL-sats refererar till en vy som har en INSTEAD OF-utlösare definierad, kör databassystemet den utlösaren istället för att göra något på vilken tabell som helst. Denna triggertyp använder alltid informationen i de infogade och borttagna tabellerna som skapats för vyn för att skapa alla uttalanden som krävs för att skapa den begärda händelsen.

Kolumnvärdena som tillhandahålls av INSTEAD OF -utlösaren måste uppfylla vissa krav:

    värden kan inte anges för beräknade kolumner;

    värden kan inte anges för tidsstämpelkolumner;

    värden kan inte anges för kolumner med egenskapen IDENTITY, om inte parametern IDENTITY_INSERT är inställd på PÅ.

Dessa krav är endast giltiga för INSERT- och UPDATE -uttalanden som refererar till grundtabeller. Ett INSERT-uttalande som refererar till vyer med en INSTEAD OF-utlösare måste tillhandahålla värden för alla kolumner som inte kan upphävas i den vyn. (Detsamma gäller UPDATE-satsen. En UPDATE-sats som refererar till en vy med en INSTEAD OF-utlösare måste tillhandahålla värden för alla kolumner i den icke-nullable-vy som refereras till i SET-satsen.)

Exemplet nedan illustrerar skillnaden i beteende när du sätter in värden i beräknade kolumner med hjälp av en tabell och dess motsvarande vy:

ANVÄND SampleDb; SKAPA TABELL Beställningar (OrderId INT NOT NULL, Price PENGE NOT NULL, Quantity INT NOT NULL, OrderDate DATETIME NOT NULL, Total AS Price * Quantity, ShippedDATE AS DATEADD (DAY, 7, orderdate)); GO CREATE VIEW view_AllOrders SOM SELECT * FRÅN beställningar; GO CREATE TRIGGER trigger_orders ON view_AllOrders INSTEAD OF INSERT AS BEGIN INSERT INTO Orders SELECT OrderId, Price, Quantity, OrderDate FROM insert END

I det här exemplet används tabellen Beställningar, som innehåller två beräknade kolumner. Vyn view_AllOrders innehåller alla rader i den här tabellen. Denna vy används för att ange ett värde i kolumnen som motsvarar en beräknad kolumn i den underliggande tabellen som vyn skapas på. Detta möjliggör användning av en INSTEAD OF -utlösare, som i fallet med en INSERT -sats ersätts av ett paket som infogar värdena i grundtabellen genom vyn view_AllOrders. (En INSERT -sats som hänvisar direkt till den underliggande tabellen kan inte ange ett värde till en beräknad kolumn.)

Första och sista triggers

Med Database Engine kan du skapa flera utlösare för varje tabell eller vy och för varje operation (INSERT, UPDATE och DELETE) på dem. Dessutom kan du ange exekveringsorder för flera triggers som definierats för en specifik operation. Använda ett systemförfarande sp_settriggerorder du kan ange att en av AFTER -utlösarna som definierats för tabellen kommer att köras först eller sist för varje åtgärd som bearbetas. Denna systemprocedur har en @order -parameter som kan tilldelas ett av tre värden:

    första - indikerar att utlösaren är den första EFTER -utlösaren som utförs för att ändra åtgärden;

    sista - indikerar att denna utlösare är den sista EFTER -utlösaren som utfördes för att initiera en åtgärd;

    ingen - Anger att det inte finns någon specifik exekveringsorder för utlösaren. (Det här värdet används vanligtvis för att återställa en tidigare inställd utlösningsorder för första eller sista.)

Att ändra strukturen för en utlösare med ALTER TRIGGER -satsen reverserar ordningen i vilken utlösaren körs (första eller sista). Användningen av sp_settriggerorder -systemproceduren visas i exemplet nedan:

ANVÄND SampleDb; EXEC sp_settriggerorder @triggername = "trigger_ModifyBudget", @order = "första", @stmttype = "uppdatering"

Endast en första och endast en sista EFTER -utlösare är tillåten för ett bord. Resten av AFTER -utlösarna körs i ospecificerad ordning. Du kan ta reda på ordningsföljden för en utlösare med hjälp av systemproceduren sp_helptrigger eller funktionen OBJECTPROPERTY.

Resultatuppsättningen som returneras av systemproceduren sp_helptrigger innehåller en orderkolumn som anger i vilken ordning den angivna utlösaren körs. När du anropar objektobjektfunktionen anger dess andra parameter värdet ExeclsFirstTrigger eller ExeclsLastTrigger, och den första parametern anger alltid databasobjektets identifieringsnummer. Om egenskapen som anges i den andra parametern är sann returnerar funktionen 1.

Eftersom en INSTEAD OF -utlösare körs innan några ändringar görs i tabellen, kan denna utlösartyp inte anges som "första" eller "sista".

DDL -triggers och deras användningsområden

Tidigare tittade vi på DML -triggers som anger vilken åtgärd servern vidtar när en tabell ändras med en INSERT, UPDATE eller DELETE -sats. Med Database Engine kan du också definiera utlösare för DDL -satser som SKAPA DATABASE, DROP TABLE och ALTER TABLE. Utlösare för DDL -satser har följande syntax:

SKAPA TRIGGER trigger_name ON (ALL SERVER | DATABASE) (FOR | EFTER) (event_group | event_type | LOGON) AS (batch | EXTERNAL NAME method_name) Syntaxkonventioner

Som du kan se från deras syntax skapas DDL -triggers på samma sätt som DML -triggers. Och för att ändra och ta bort dessa utlösare, använd samma ALTER TRIGGER och DROP TRIGGER -satser som för DML -triggers. Därför täcker detta avsnitt endast de parametrarna i CREATE TRIGGER -satsen som är nya för syntaxen för DDL -triggers.

Det första steget i att definiera en DDL -utlösare är att ange dess omfattning. DATABASE -klausul anger den aktuella databasen som omfattningen av DDL -utlösaren och ALL SERVER -erbjudande- den aktuella servern.

När du har angett omfattningen av en DDL -utlösare måste du ange hur utlösaren ska köras som svar på en eller flera DDL -satser. Event_type-parametern anger DDL-satsen som kör utlösaren och den alternativa eventgruppen anger Transact-SQL-händelsegruppen. DDL-utlösaren avfyras vid körning av alla Transact-SQL-händelser som anges i parametern event_group. Nyckelord LOGGA IN indikerar en inloggningsutlösare.

Förutom likheterna mellan DML- och DDL -utlösare finns det också flera skillnader mellan dem. Den största skillnaden mellan de två typerna av triggers är att en DDL -utlösare kan omfattas av hela databasen, eller till och med hela servern, snarare än bara ett enda objekt. Dessutom stöder inte DDL -triggers INSTEAD OF triggers. Som du kanske har gissat krävs inte de infogade och borttagna tabellerna för DDL -utlösare, eftersom dessa utlösare inte ändrar innehållet i tabellerna.

Följande undersektioner beskriver två former av DDL-utlösare: utlösare på databasnivå och utlösare på servernivå.

DDL-utlösare på databasnivå

Exemplet nedan visar hur du kan implementera en DDL -utlösare som omfattas av den aktuella databasen:

ANVÄND SampleDb; GO CREATE TRIGGER trigger_PreventDrop ON DATABASE FOR DROP_TRIGGER AS PRINT "Innan du släpper en trigger måste du inaktivera" trigger_PreventDrop "" ROLLBACK

Utlösaren i det här exemplet förhindrar att någon användare tar bort alla utlösare i SampleDb -databasen. DATABASE-satsen anger att trigger_PreventDrop är en utlösare på databasnivå. Nyckelord DROP_TRIGGER anger en fördefinierad händelsestyp som tillåter borttagning av någon utlösare.

Server-nivå DDL-triggers

Utlösare på servernivå svarar på händelser på serversidan. En utlösare på servernivå skapas med hjälp av ALL SERVER-satsen i CREATE TRIGGER-satsen. Beroende på vilken åtgärd utlösaren utför finns det två olika typer av servernivåutlösare: vanliga DDL-utlösare och inloggningsutlösare. Vanliga DDL -utlösare avfyras baserat på DDL -uttalandehändelser och inloggningsutlösare avfyras baserat på inloggningshändelser.

Exemplet nedan visar hur du skapar en utlösare på servernivå som är en inloggningsutlösare:

ANVÄND master; GO CREATE LOGIN loginTest WITH PASSWORD = "12345!", CHECK_EXPIRATION = ON; GO GRANT VIEW SERVER STATE TO loginTest; GO CREATE TRIGGER trigger_ConnectionLimit ON ALL SERVER WITH EXECUTE AS "loginTest" FOR LOGON AS BEGIN IF ORIGINAL_LOGIN () = "loginTest" AND (SELECT COUNT (*) FROM sys.dm_exec_sessions WHERE is_user_processname = 1 AND> original_est; SLUTET;

Här skapas först inloggningstestet för SQL Server, som sedan används i en utlösare på servernivå. Av denna anledning kräver denna inloggning VIEW SERVER STATE -tillstånd, som beviljas genom GRANT -uttalandet. Därefter skapas trigger_ConnectionLimit -utlösaren. Denna utlösare är en inloggningsutlösare som indikeras av LOGON -sökordet.

Använda vyn sys.dm_exec_sessions kontrollerar om en session redan har upprättats med hjälp av inloggningstestet. Om sessionen redan har upprättats körs ROLLBACK -satsen. Därför kan inloggningstestet bara skapa en session i taget.

Utlösare och CLR

Liksom lagrade procedurer och användardefinierade funktioner kan triggers implementeras med hjälp av Common Language Runtime (CLR). CLR -triggers skapas i tre steg:

    Utlösarkällkoden genereras i C # eller Visual Basic och kompileras sedan med lämplig kompilator för att objektkod.

    Objektkoden bearbetas av CREATE ASSEMBLY -satsen och skapar motsvarande körbar fil.

    En trigger skapas med CREATE TRIGGER -satsen.

Följande exempel visar hur du slutför alla dessa tre steg för att skapa en CLR -utlösare. Nedan visas ett exempel på C # -källkoden för utlösaren från det första exemplet i artikeln. Innan du skapar CLR -utlösaren i följande exempel måste du först släppa trigger_PreventDrop och sedan släppa trigger_ModifyBudget med DROP TRIGGER -satsen i båda fallen.

Använda System; med System.Data.SqlClient; med Microsoft.SqlServer.Server; public class Triggers (public static void ModifyBudget () (SqlTriggerContext context = SqlContext.TriggerContext; if (context.IsUpdatedColumn (2)) // Kolumn Budget (float budget_old; float budget_new; string connection project_number; SqlConnection SqlConnection ); conn.Open (); SqlCommand cmd = conn.CreateCommand (); cmd.CommandText = "VÄLJ budget FRÅN RADERAD"; budget_old = (float) Convert.ToDouble (cmd.ExecuteScalar ()); cmd.CommandText = "SELECT Budget FROM INSERTED "; budget_new = (float) Convert.ToDouble (cmd.ExecuteScalar ()); cmd.CommandText =" SELECT Number FROM DELETED "; 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.Add "@budgetOld", budget_old) ; cmd.Parameters.AddWithValue (" @ budgetNew", budget_new); cmd.ExecuteNonQuery ();)) )

Namnutrymmet Microsoft.SQLServer.Server innehåller alla klientklasser som ett C # -program kan behöva. Klasser SqlTriggerContext och SqlFunktionär medlemmar i detta namnområde. Dessutom innehåller System.Data.SqlClient -namnutrymmet SqlConnection- och SqlCommand -klasserna som används för att upprätta anslutning och kommunikation mellan klienten och databasservern. Anslutningen upprättas med anslutningssträngen "context connection = true".

Sedan definieras Triggers -klassen, som används för att implementera triggers. Metoden ModifyBudget () implementerar utlösaren med samma namn. Kontextinstansen för SqlTriggerContext -klassen tillåter ett program att komma åt den virtuella tabellen som skapas när utlösaren körs. Den här tabellen lagrar data som orsakade utlösaren. Metoden IsUpdatedColumn () i klassen SqlTriggerContext låter dig veta om den angivna tabellkolumnen har uppdaterats.

Detta program innehåller två andra viktiga klasser: SqlConnection och SqlCommand. En instans av SqlConnection -klassen används vanligtvis för att upprätta en anslutning till en databas, medan en instans av SqlCommand -klassen låter dig köra SQL -satser.

Programmet i detta exempel kan kompileras med csc -kompilatorn som är inbyggd i Visual Studio. Nästa steg är att lägga till en referens till den kompilerade enheten i databasen:

ANVÄND SampleDb; GO CREATE ASSEMBLY CLRStoredProcedures FROM "D: \ Projects \ CLRStoredProcedures \ bin \ Debug \ CLRStoredProcedures.dll" WITH PERMISSION_SET = SAFE

CREATE ASSEMBLY -satsen tar hanterad kod som inmatning och skapar ett lämpligt objekt för att skapa en CLR -utlösare. Klausulen WITH PERMISSION_SET i exemplet anger att åtkomstbehörigheterna är inställda på SAFE.

Slutligen skapar exemplet nedan en trigger_modify_budget med hjälp av CREATE TRIGGER -satsen:

ANVÄND SampleDb; GO CREATE TRIGGER trigger_modify_budget ON Project EFTER UPDATE AS EXTERNAL NAME CLRStoredProcedures.Triggers.ModifyBudget

CREATE TRIGGER -satsen i exemplet skiljer sig från samma sats i exemplen tidigare i det den innehåller EXTERNAL NAME parameter... Denna parameter indikerar att koden genereras av CLR. Namnet i denna parameter har tre delar. Den första delen anger namnet på motsvarande församling (CLRStoredProcedures), den andra anger namnet på den offentliga klassen som definieras i exemplet ovan (utlösare) och den tredje anger namnet på metoden som definieras i denna klass (ModifyBudget).







2021 gtavrl.ru.