Megosztás a következőn keresztül:


LÉTREHOZNI TRIGGERET (Transact-SQL)

A következőkre vonatkozik:SQL ServerAzure SQL DatabaseFelügyelt Azure SQL-példánySQL-adatbázis a Microsoft Fabricben

Létrehoz egy DML-, DDL- vagy bejelentkezési eseményindítót. Az eseményindító egy speciális típusú tárolt eljárás, amely automatikusan fut, amikor esemény történik az adatbázis-kiszolgálón. A DML-eseményindítók akkor futnak, amikor egy felhasználó adatmanipulációs nyelv (DML) eseményen keresztül próbál adatokat módosítani. A DML-események táblázaton INSERTvagy UPDATE nézetben lévő DELETEutasítások. Ezek az eseményindítók akkor aktiválódnak, amikor bármilyen érvényes esemény aktiválódik, függetlenül attól, hogy a táblasorok érintettek-e vagy sem. További információ: DML-eseményindítók.

A DDL-eseményindítók különböző adatdefiníciós nyelvi (DDL-) eseményekre reagálva futnak. Ezek az események elsősorban Transact-SQL CREATE, ALTERés DROP utasításoknak, valamint bizonyos, DDL-szerű műveleteket végző rendszer által tárolt eljárásoknak felelnek meg.

A bejelentkezés aktiválja a LOGON felhasználó munkamenetének létrehozásakor felmerülő eseményt. Az eseményindítókat közvetlenül Transact-SQL utasításokból vagy a Microsoft .NET-keretrendszer közös nyelvi futtatókörnyezetében (CLR) létrehozott és az SQL Server egy példányára feltöltött szerelvények metódusaiból hozhatja létre. Az SQL Server lehetővé teszi, hogy több eseményindítót hozzon létre egy adott utasításhoz.

Fontos

Az eseményindítókon belüli rosszindulatú kódok eszkalált jogosultságok alatt futtathatók. A fenyegetés elhárításáról további információt az eseményindítók biztonságának kezelése című témakörben talál.

Megjegyzés:

NET-keretrendszer CLR SQL Server integrációját ebben a cikkben tárgyaljuk. A CLR integráció nem vonatkozik Azure SQL Database-re vagy SQL adatbázisra a Microsoft Fabric-ben.

Transact-SQL szintaxis konvenciók

Szemantika

SQL Server-szintaxis

Eseményindító táblán INSERTUPDATEvagy DELETE nézeten (DML-eseményindító):

CREATE [ OR ALTER ] TRIGGER [ schema_name . ] trigger_name
ON { table | view }
[ WITH <dml_trigger_option> [ , ...n ] ]
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
[ WITH APPEND ]
[ NOT FOR REPLICATION ]
AS { sql_statement  [ ; ] [ , ...n ] | EXTERNAL NAME <method_specifier [ ; ] > }

<dml_trigger_option> ::=
    [ ENCRYPTION ]
    [ EXECUTE AS Clause ]

<method_specifier> ::=
    assembly_name.class_name.method_name

Eseményindító egy INSERTtáblához , UPDATEvagy DELETE utasításhoz (DML-eseményindító memóriaoptimalizált táblákon):

CREATE [ OR ALTER ] TRIGGER [ schema_name . ] trigger_name
ON { table }
[ WITH <dml_trigger_option> [ , ...n ] ]
{ FOR | AFTER }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
AS { sql_statement  [ ; ] [ , ...n ] }

<dml_trigger_option> ::=
    [ NATIVE_COMPILATION ]
    [ SCHEMABINDING ]
    [ EXECUTE AS Clause ]

Eseményindító egy CREATE, ALTER, DROP, GRANT, DENY, REVOKE, vagy UPDATE utasításon (DDL-eseményindító):

CREATE [ OR ALTER ] TRIGGER trigger_name
ON { ALL SERVER | DATABASE }
[ WITH <ddl_trigger_option> [ , ...n ] ]
{ FOR | AFTER } { event_type | event_group } [ , ...n ]
AS { sql_statement  [ ; ] [ , ...n ] | EXTERNAL NAME < method specifier >  [ ; ] }

<ddl_trigger_option> ::=
    [ ENCRYPTION ]
    [ EXECUTE AS Clause ]

Esemény eseményindítója LOGON (bejelentkezési eseményindító):

CREATE [ OR ALTER ] TRIGGER trigger_name
ON ALL SERVER
[ WITH <logon_trigger_option> [ , ...n ] ]
{ FOR | AFTER } LOGON
AS { sql_statement  [ ; ] [ , ...n ] | EXTERNAL NAME < method specifier >  [ ; ] }

<logon_trigger_option> ::=
    [ ENCRYPTION ]
    [ EXECUTE AS Clause ]

Azure SQL Database vagy SQL Database a Fabric szintaxisában

Eseményindító táblán INSERTUPDATEvagy DELETE nézeten (DML-eseményindító):

CREATE [ OR ALTER ] TRIGGER [ schema_name . ] trigger_name
ON { table | view }
 [ WITH <dml_trigger_option> [ , ...n ] ]
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
  AS { sql_statement  [ ; ] [ , ...n ] [ ; ] > }

<dml_trigger_option> ::=
        [ EXECUTE AS Clause ]

Eseményindító egy CREATE, ALTER, DROP, GRANT, DENY, REVOKE, vagy UPDATE STATISTICS utasításon (DDL-eseményindító):

CREATE [ OR ALTER ] TRIGGER trigger_name
ON { DATABASE }
 [ WITH <ddl_trigger_option> [ , ...n ] ]
{ FOR | AFTER } { event_type | event_group } [ , ...n ]
AS { sql_statement  [ ; ] [ , ...n ]  [ ; ] }

<ddl_trigger_option> ::=
    [ EXECUTE AS Clause ]

Érvek

VAGY ALTER

Alkalmazható: SQL Server 2016 (13.x) SP1 és újabb verziók, Azure SQL Database, valamint SQL adatbázis Microsoft Fabric-ben.

Feltételesen csak akkor módosítja az eseményindítót, ha már létezik.

schema_name

Annak a sémának a neve, amelyhez egy DML-eseményindító tartozik. A DML-eseményindítók hatóköre annak a táblának vagy nézetnek a sémájára terjed ki, amelyen létrehozták őket. schema_name nem adható meg DDL- vagy bejelentkezési eseményindítókhoz.

trigger_name

Az eseményindító neve. A trigger_name az azonosítókra vonatkozó szabályokat kell követnie, azzal a kivétellel, hogy trigger_name nem kezdődhet a következővel # : vagy ##.

asztal | nézet

Az a tábla vagy nézet, amelyen a DML-eseményindító fut. Ezt a táblát vagy nézetet néha triggertáblának vagy eseményindító nézetnek is nevezik. A tábla vagy nézet teljes nevének megadása nem kötelező. Csak eseményindítóval hivatkozhat nézetre INSTEAD OF . Helyi vagy globális ideiglenes táblákon nem definiálhat DML-eseményindítókat.

ADATBÁZIS

Egy DDL-eseményindító hatókörét alkalmazza az aktuális adatbázisra. Ha meg van adva, az eseményindító minden alkalommal aktiválódik, amikor event_type vagy event_group történik az aktuális adatbázisban.

MINDEN KISZOLGÁLÓ

Egy DDL- vagy bejelentkezési eseményindító hatókörét alkalmazza az aktuális kiszolgálóra. Ha meg van adva, az eseményindító minden alkalommal aktiválódik, amikor event_type vagy event_group az aktuális kiszolgálón bárhol előfordul.

TITKOSÍTÁSSAL

Elhomályosítja az utasítás szövegét CREATE TRIGGER . A használat WITH ENCRYPTION megakadályozza az eseményindító közzétételét az SQL Server-replikáció részeként. WITH ENCRYPTION nem adható meg a CLR-eseményindítókhoz.

VÉGREHAJTÁS MÁSKÉNT

Megadja az eseményindító végrehajtásának biztonsági környezetét. Lehetővé teszi annak szabályozását, hogy az SQL Server példánya melyik felhasználói fiókot használja az eseményindító által hivatkozott adatbázis-objektumok engedélyeinek érvényesítéséhez.

Ez a beállítás a memóriaoptimalizált táblák eseményindítóihoz szükséges.

További információt az EXECUTE AS záradékban talál.

NATIVE_COMPILATION

Azt jelzi, hogy az eseményindító natív módon van lefordítva.

Ez a beállítás a memóriaoptimalizált táblák eseményindítóihoz szükséges.

SÉMAKÖTÉS

Biztosítja, hogy az eseményindítók által hivatkozott táblákat ne lehessen elvetni vagy módosítani.

Ez a beállítás a memóriaoptimalizált táblák eseményindítóihoz szükséges, és a hagyományos táblák eseményindítói esetében nem támogatott.

FOR | UTÁN

FOR vagy AFTER azt határozza meg, hogy a DML-eseményindító csak akkor aktiválódik, ha az eseményindító SQL-utasításban megadott összes művelet sikeresen elindult. Az eseményindító elindítása előtt minden hivatkozási kaszkádolt műveletnek és kényszer-ellenőrzésnek sikeresnek kell lennie.

A nézetekben nem definiálhat AFTER eseményindítókat.

AHELYETT, HOGY

Megadja, hogy a DML-eseményindító az aktiváló SQL-utasítás helyett indul el, így felülírva az eseményindító utasítások műveleteit. DDL- vagy bejelentkezési eseményindítókhoz nem adható meg INSTEAD OF .

Legfeljebb egy INSTEAD OF eseményindítót definiálhat egy táblán vagy nézeten, illetve INSERT utasításonkéntUPDATEDELETE. Olyan nézeteket is meghatározhat, ahol minden nézet saját INSTEAD OF eseményindítóval rendelkezik.

Nem definiálhat INSTEAD OF eseményindítókat az olyan frissíthető nézeteken, amelyek használják WITH CHECK OPTION. Ha így tesz, hibaüzenet jelenik meg, ha egy INSTEAD OF eseményindító hozzáadódik egy frissíthető nézethez WITH CHECK OPTION . Ezt a beállítást ALTER VIEW az eseményindító definiálása INSTEAD OF előtt távolíthatja el.

{ [ TÖRLÉS ] [ , ] [ BEKERÜLÉS ] [ , ] [ FRISSÍTÉS ] }

Megadja azokat az adatmódosítási utasításokat, amelyek aktiválják a DML-eseményindítót, amikor a tábla vagy nézet ellen próbálják. Adjon meg legalább egy lehetőséget. Ezeket a beállításokat bármilyen sorrendben használhatja az eseményindító definíciójában.

Eseményindítók esetén INSTEAD OF nem használható a DELETE hivatkozási kapcsolattal rendelkező táblákban a kaszkádolt művelet ON DELETEmegadása. Hasonlóképpen, a UPDATE beállítás nem engedélyezett a hivatkozási kapcsolattal rendelkező táblákon, és kaszkádolt műveletet ON UPDATEad meg.

HOZZÁFŰZÉSSEL

A következőkre vonatkozik: SQL Server 2008 (10.0.x) és SQL Server 2008 R2 (10.50.x).

Megadja, hogy egy meglévő típusú további eseményindítót kell hozzáadni. WITH APPEND nem használható eseményindítókkal INSTEAD OF , vagy ha egy AFTER eseményindító explicit módon van feltüntetve. A visszamenőleges kompatibilitás érdekében csak akkor használja WITH APPEND , ha FOR meg van adva, anélkül INSTEAD OF vagy AFTERanélkül. Nem adhatja meg WITH APPEND , hogy használja-e EXTERNAL NAME (vagyis hogy az eseményindító CLR-eseményindító-e).

event_type

Egy Transact-SQL nyelvi esemény neve, amely az indítás után elindít egy DDL-eseményindítót. A DDL-eseményindítók érvényes eseményei szerepelnek a DDL-események között.

event_group

Az Transact-SQL nyelvi események előre definiált csoportosításának neve. A DDL-eseményindító a event_group Transact-SQL nyelvi eseményének elindítása után aktiválódik. A DDL-eseményindítók érvényes eseménycsoportjai a DDL-eseménycsoportokban jelennek meg.

A futtatás befejezése után CREATE TRIGGER makróként is működik, ha hozzáadja az általa lefedett eseménytípusokat a sys.trigger_events katalógusnézethez.

REPLIKÁCIÓHOZ NEM

Azt jelzi, hogy az eseményindítót nem szabad futtatni, ha egy replikációs ügynök módosítja az eseményindítóban részt vevő táblát.

sql_statement

Az eseményindító feltételei és műveletei. Az eseményindítók feltételei további feltételeket határoznak meg, amelyek meghatározzák, hogy a kipróbált DML-, DDL- vagy bejelentkezési események okozzák-e a triggerműveleteket.

A Transact-SQL utasításokban megadott triggerműveletek a művelet kipróbálásakor lépnek érvénybe.

Az eseményindítók tartalmazhatnak tetszőleges számú és típusú Transact-SQL utasítást, kivételekkel. További információ: Megjegyzések. Az eseményindítók az adatok adatmódosítási vagy definíciós utasításon alapuló ellenőrzésére vagy módosítására szolgálnak. Az eseményindítónak nem szabad adatokat visszaadnia a felhasználónak. Az eseményindítók Transact-SQL utasításai gyakran magukban foglalják a folyamatvezérlés nyelvét.

A DML-eseményindítók a törölt és beszúrt logikai (elméleti) táblákat használják. Szerkezetileg hasonlóak ahhoz a táblához, amelyen az eseményindító definiálva van, vagyis ahhoz a táblához, amelyen a felhasználói műveletet megpróbálják. A törölt és beszúrt táblák a felhasználói művelet által esetleg módosított sorok régi vagy új értékeit tartalmazzák. Például a tábla összes értékének lekéréséhez használja a deleted következőt:

SELECT * FROM deleted;

További információ: A beszúrt és törölt táblák használata.

A DDL és a bejelentkezési eseményindítók az EVENTDATA függvény használatával rögzítik az eseményindító esemény adatait. További információ: Az EVENTDATA függvény használata.

Az SQL Server lehetővé teszi a szöveg-, ntext- vagy képoszlopok frissítését az eseményindítón keresztül táblákon INSTEAD OF vagy nézeteken.

Fontos

Az ntext, a szöveg és a kép adattípusai a Microsoft SQL Server egy későbbi verziójában törlődnek. Ne használja ezeket az adattípusokat az új fejlesztési munkában, és tervezze meg a jelenleg használt alkalmazások módosítását. Használja inkább az nvarchar(max), a varchar(max) és a varbinary(max) függvényt. Mind AFTER a INSTEAD OF triggerek támogatják a varchar(max), az nvarchar(max) és a varbinary(max) adatokat a beszúrt és törölt táblákban.

A memóriaoptimalizált táblák eseményindítói esetében az egyetlen sql_statement , amely a legfelső szinten engedélyezett, egy ATOMIC blokk. A blokkon belül ATOMIC engedélyezett T-SQL-t a Natív procsben engedélyezett T-SQL korlátozza.

<method_specifier>

A CLR-eseményindítók esetében meg kell adni egy szerelvény metódusát az eseményindítóhoz való kötéshez. A metódusnak nem szabad argumentumokat használnia, és érvénytelennek kell lennie. class_name érvényes SQL Server-azonosítónak kell lennie, és osztályként kell léteznie a szerelvényben a szerelvény láthatóságával. Ha az osztály névtér-minősített névvel rendelkezik, amely a névtérrészek elválasztására használható . , az osztály nevét [] vagy " " határolójellel kell elválasztani. Az osztály nem lehet beágyazott osztály.

Megjegyzés:

Alapértelmezés szerint az SQL Server clr-kód futtatásának képessége ki van kapcsolva. Létrehozhat, módosíthat és elvethet olyan adatbázis-objektumokat, amelyek felügyelt kódmodulokra hivatkoznak, de ezek a hivatkozások csak akkor futnak az SQL Server egy példányában, ha a clr-kompatibilis beállítás engedélyezve van sp_configure.

DML-eseményindítók megjegyzései

A DML-eseményindítókat gyakran használják az üzleti szabályok és az adatintegritás kényszerítésére. Az SQL Server deklaratív hivatkozási integritást (DRI) biztosít az ALTER TABLE utasításokon CREATE TABLE keresztül. A DRI azonban nem biztosít adatbázisközi hivatkozási integritást. A hivatkozási integritás a táblák elsődleges és idegen kulcsai közötti kapcsolatokra vonatkozó szabályokat jelenti. A hivatkozási integritás érvényesítéséhez használja az és a PRIMARY KEYFOREIGN KEYALTER TABLECREATE TABLE. Ha a triggertáblán korlátozások vannak, akkor a rendszer az INSTEAD OF eseményindító futtatása után és az eseményindító futtatása előtt ellenőrzi őket AFTER . Ha a korlátozások sérülnek, a rendszer visszaállítja a INSTEAD OF triggerműveleteket, és nem aktiválja az AFTER eseményindítót.

A táblán futtatandó első és utolsó AFTER eseményindítókat a használatával sp_settriggerorderadhatja meg. Egy táblán AFTERINSERTUPDATE csak egy első és egy utolsó DELETE eseményindítót és műveletet adhat meg. Ha ugyanazon a táblán más AFTER eseményindítók is találhatók, véletlenszerűen futnak.

Ha egy ALTER TRIGGER utasítás módosít egy első vagy utolsó eseményindítót, a módosított eseményindítón beállított első vagy utolsó attribútum el lesz dobva, és a rendelés értékét a következővel sp_settriggerorderkell alaphelyzetbe állítania: .

Az AFTER eseményindító csak az sql-utasítás sikeres futtatása után fut. Ez a sikeres végrehajtás magában foglalja a frissített vagy törölt objektumhoz társított összes hivatkozási kaszkádolt műveletet és kényszerellenőrzést. Egy AFTER eseményindító nem rekurzív módon aktiválódik INSTEAD OF ugyanazon a táblán.

Ha egy táblában definiált INSTEAD OF eseményindító olyan utasítást futtat a táblán, amely általában újra elindítja az INSTEAD OF eseményindítót, az eseményindító nem rekurzívan lesz meghívva. Ehelyett az utasítás úgy dolgozza fel a folyamatot, mintha a táblában nem INSTEAD OF lett volna eseményindító, és elindítja a kényszerműveletek és AFTER az eseményindító-végrehajtások láncát. Ha például egy eseményindító egy tábla eseményindítójaként INSTEAD OF INSERT van definiálva. Ha az eseményindító egy utasítást INSERT futtat ugyanazon a táblán, az INSERTINSTEAD OF eseményindító által indított utasítás nem hívja meg újra az eseményindítót. Az INSERT eseményindító elindítja a kényszerműveletek futtatását és a táblához definiált AFTER INSERT triggerek indítását.

Ha egy nézetben definiált INSTEAD OF eseményindító olyan utasítást futtat a nézeten, amely általában újra elindítja az INSTEAD OF eseményindítót, az nem rekurzívan van meghívva. Ehelyett az utasítás a nézet alapjául szolgáló alaptáblák módosításaiként lesz feloldva. Ebben az esetben a nézetdefiníciónak meg kell felelnie az frissíthető nézetre vonatkozó összes korlátozásnak. Az frissíthető nézetek definícióját lásd: Adatok módosítása nézeten keresztül.

Ha például egy eseményindító egy nézet eseményindítójaként INSTEAD OF UPDATE van definiálva. Az eseményindító pedig egy UPDATE azonos nézetre hivatkozó utasítást futtat, az UPDATEINSTEAD OF eseményindító által indított utasítás nem hívja meg újra az eseményindítót. Az UPDATE eseményindító által indított folyamat úgy lesz feldolgozva a nézeten, mintha a nézet nem rendelkezik eseményindítóval INSTEAD OF . A módosított UPDATE oszlopokat egyetlen alaptáblára kell feloldani. A mögöttes alaptáblák minden módosítása elindítja a táblához definiált kényszerek és aktiváló AFTER triggerek alkalmazásának láncát.

UPDATE vagy INSERT műveletek tesztelése adott oszlopokra

Egy Transact-SQL eseményindítót úgy tervezhet meg, hogy bizonyos műveleteket bizonyos oszlopok alapján UPDATE vagy INSERT módosításokkal hajthat végre. Ehhez használja az UPDATE vagy COLUMNS_UPDATED az eseményindító törzsében. UPDATE() egy oszlopra vonatkozó UPDATE teszteket vagy INSERT kísérleteket. COLUMNS_UPDATED UPDATE több oszlopon futó tesztek vagy INSERT műveletek. Ez a függvény egy bitmintát ad vissza, amely jelzi, hogy mely oszlopok lettek beszúrva vagy frissítve.

Eseményindító korlátozásai

CREATE TRIGGER a köteg első utasításának kell lennie, és csak egy táblára alkalmazható.

Az eseményindító csak az aktuális adatbázisban jön létre; az eseményindítók azonban hivatkozhatnak az aktuális adatbázison kívüli objektumokra.

Ha az eseményindító sémaneve meg van adva az eseményindító minősítéséhez, a tábla nevét ugyanúgy minősítse.

Ugyanaz az eseményindító művelet több felhasználói művelethez is definiálható (például INSERTUPDATE) ugyanabban CREATE TRIGGER az utasításban.

INSTEAD OF DELETE / INSTEAD OF UPDATE az eseményindítók nem határozhatók meg olyan táblán, amely egy külső kulccsal rendelkező, kaszkádolt DELETE/UPDATE művelettel rendelkezik.

Bármely SET utasítás megadható egy eseményindítón belül. A kiválasztott SET beállítás az eseményindító végrehajtása során is érvényben marad, majd visszaáll a korábbi beállítására.

Amikor egy eseményindító aktiválódik, a rendszer a tárolt eljárásokhoz hasonlóan visszaadja az eredményeket a hívó alkalmazásnak. Ha meg szeretné akadályozni, hogy az eredmények egy eseményindító tüzelése miatt visszakerüljenek egy alkalmazásba, ne tartalmazzon SELECT olyan utasításokat, amelyek eredményeket adnak vissza, vagy olyan utasításokat, amelyek változó hozzárendelést végeznek egy eseményindítóban. Egy olyan eseményindító, amely vagy olyan utasításokat tartalmaz SELECT , amelyek eredményeket adnak vissza a felhasználónak, vagy a változó hozzárendelést végző utasítások speciális kezelést igényelnek. A visszaadott eredményeket minden olyan alkalmazásba be kell írnia, amelyben engedélyezve van a triggertábla módosítása. Ha a változó-hozzárendelésnek eseményindítóban kell történnie, az eseményindító elején található SET NOCOUNT utasítással megakadályozhatja az eredményhalmazok visszatérését.

Bár az TRUNCATE TABLE utasítás valójában utasítás DELETE , nem aktivál egy eseményindítót, mert a művelet nem naplózza az egyes sorok törlését. Azonban csak azoknak a felhasználóknak kell aggódniukTRUNCATE TABLE, akik engedéllyel rendelkeznek egy DELETE utasítás futtatásához.

A WRITETEXT naplózott vagy a nem megjelölt utasítás nem aktivál egy eseményindítót.

A következő Transact-SQL utasítások nem engedélyezettek DML-eseményindítókban:

  • ALTER DATABASE
  • CREATE DATABASE
  • DROP DATABASE
  • RESTORE DATABASE
  • RESTORE LOG
  • RECONFIGURE

Ezenkívül a következő Transact-SQL utasítások nem engedélyezettek a DML-eseményindító törzsében, ha azokat az eseményindító művelet céltáblájára vagy nézetére használják.

  • CREATE INDEX (beleértve CREATE SPATIAL INDEX és CREATE XML INDEX)
  • ALTER INDEX
  • DROP INDEX
  • DROP TABLE
  • DBCC DBREINDEX
  • ALTER PARTITION FUNCTION
  • ALTER TABLE amikor a következő műveletek végrehajtására használják:
    • Oszlopok hozzáadása, módosítása vagy elvetése.
    • Partíciók váltása.
    • Adjon hozzá vagy csepegtetsen vagy PRIMARY KEY csepegtethet UNIQUE korlátozásokat.

Megjegyzés:

Mivel az SQL Server nem támogatja a felhasználó által definiált eseményindítókat a rendszertáblákon, javasoljuk, hogy ne hozzon létre felhasználó által definiált eseményindítókat a rendszertáblákon.

DML-eseményindítók optimalizálása

Az eseményindítók tranzakciókban (vélelmezett vagy egyéb módon) működnek, és amíg nyitva vannak, zárolják az erőforrásokat. A zárolás mindaddig érvényben marad, amíg a tranzakció megerősítést nem nyer (a ) COMMITvagy elutasítja (a ROLLBACKkövetkezővel: ). Minél hosszabb ideig fut egy eseményindító, annál nagyobb a valószínűsége annak, hogy egy másik folyamat le van tiltva. Az eseményindítók írása így lehetőség szerint csökkenti az időtartamukat. A rövidebb időtartam elérésének egyik módja egy eseményindító felszabadítása, amikor egy DML-utasítás nulla sort módosít.

Ha olyan parancs eseményindítóját szeretné felszabadítani, amely nem módosítja a sorokat, alkalmazza a rendszerváltozót ROWCOUNT_BIG.

Az alábbi T-SQL-kódrészlet bemutatja, hogyan oldhatja fel az eseményindítót egy olyan parancshoz, amely nem módosítja a sorokat. Ennek a kódnak minden DML-eseményindító elején jelen kell lennie:

IF (ROWCOUNT_BIG() = 0)
RETURN;

DDL-eseményindítók megjegyzései

A DDL-eseményindítók, például a standard triggerek, egy eseményre válaszul elindítják a tárolt eljárásokat. A szabványos eseményindítókkal ellentétben azonban nem a táblában vagy nézetben lévő , UPDATEvagy INSERT utasításokra DELETEadott válaszként futnak. Ehelyett elsősorban adatdefiníciós nyelvi (DDL-) utasításokra reagálva futnak. Az utasítástípusok a következők: CREATE, ALTER, DROP, GRANT, DENYREVOKEés UPDATE STATISTICS. Bizonyos, DDL-hez hasonló műveleteket végző rendszer által tárolt eljárások DDL-triggereket is aktiválhatnak.

Fontos

Tesztelje a DDL-eseményindítókat a rendszer által tárolt eljárás végrehajtására adott válaszok meghatározásához. Az utasítás és CREATE TYPE a sp_addtypesp_rename tárolt eljárások például elindítanak egy eseményen létrehozott DDL-eseményindítót CREATE_TYPE .

A DDL-eseményindítókkal kapcsolatos további információkért lásd a DDL-eseményindítókat.

A DDL-eseményindítók nem aktiválhatók a helyi vagy globális ideiglenes táblákat és tárolt eljárásokat érintő eseményekre válaszul.

A DML-eseményindítókkal ellentétben a DDL-eseményindítók nem terjednek ki sémákra. Így nem használhat olyan függvényeket, mint OBJECT_IDa , OBJECT_NAME, OBJECTPROPERTYés OBJECTPROPERTYEX nem kérdezhet le metaadatokat a DDL-eseményindítókról. Használja inkább a katalógusnézeteket. További információt a DDL-eseményindítókról szóló információk lekérése című témakörben talál.

Megjegyzés:

A kiszolgálói hatókörű DDL-eseményindítók az SQL Server Management Studio Object Explorerben jelennek meg az Eseményindítók mappában. Ez a mappa a Kiszolgálóobjektumok mappa alatt található. Az adatbázis-hatókörű DDL-eseményindítók az Adatbázis-eseményindítók mappában jelennek meg. Ez a mappa a megfelelő adatbázis Programozhatóság mappájában található.

Bejelentkezési eseményindítók

A bejelentkezési eseményindítók tárolt eljárásokat hajtanak végre egy LOGON eseményre válaszul. Ez az esemény akkor fordul elő, ha az SQL Server egy példányával létrejön egy felhasználói munkamenet. A bejelentkezés a naplózás hitelesítési fázisának befejeződése után, de a felhasználói munkamenet létrehozása előtt aktiválódik. Így az eseményindítón belülről érkező összes olyan üzenet, amely általában eléri a felhasználót, például a hibaüzenetek és az PRINT utasításból származó üzenetek, az SQL Server hibanaplójába kerül. További információ: Bejelentkezési eseményindítók.

A bejelentkezési eseményindítók nem indulnak el, ha a hitelesítés sikertelen.

A bejelentkezési eseményindítók nem támogatják az elosztott tranzakciókat. A 3969-s hiba akkor ad vissza, ha egy elosztott tranzakciós tüzet tartalmazó bejelentkezési eseményindítót ad vissza.

Bejelentkezési eseményindító letiltása

A bejelentkezési eseményindítók hatékonyan megakadályozhatják az adatbázismotorral való sikeres kapcsolatokat minden felhasználó számára, beleértve a sysadmin rögzített kiszolgálói szerepkör tagjait is. Ha egy bejelentkezési eseményindító megakadályozza a kapcsolatokat, a sysadmin rögzített kiszolgálói szerepkör tagjai a dedikált rendszergazdai kapcsolat használatával vagy az adatbázismotor minimális konfigurációs módban (-f) való elindításával csatlakozhatnak. További információ: Database Engine Service indítási beállításai.

Az eseményindító általános szempontjai

Eredmények visszaadása

Az eseményindítók eredményeinek visszaadása az SQL Server egy későbbi verziójában megszűnik. Az eredményhalmazokat vissza adó eseményindítók váratlan viselkedést okozhatnak azokban az alkalmazásokban, amelyek nem úgy lettek kialakítva, hogy működjenek velük. Ne adjon vissza eredményhalmazokat az új fejlesztési munkák eseményindítóiból, és tervezze meg a jelenleg használt alkalmazások módosítását. Ha meg szeretné akadályozni, hogy az eseményindítók eredményhalmazokat adjanak vissza, állítsa az eseményindítóktól származó eredmény letiltását 1 értékre.

A bejelentkezési eseményindítók mindig letiltják az eredményhalmazok visszatérését, és ez a viselkedés nem konfigurálható. Ha egy bejelentkezési eseményindító eredményhalmazt hoz létre, az eseményindító nem indul el, és a rendszer megtagadja az eseményindítót aktiváló bejelentkezési kísérletet.

Több eseményindító

Az SQL Server lehetővé teszi, hogy több eseményindítót hozzon létre minden egyes DML-hez, DDL-hez vagy LOGON eseményhez. Ha például egy olyan táblához fut, CREATE TRIGGER FOR UPDATE amely már rendelkezik eseményindítóval UPDATE , egy további frissítési eseményindító jön létre. Az SQL Server korábbi verzióiban minden táblához INSERTUPDATEcsak egy eseményindító vagy DELETE adatmódosítási esemény engedélyezett.

Rekurzív triggerek

Az SQL Server támogatja az eseményindítók rekurzív meghívását is, ha a beállítás engedélyezve van a RECURSIVE_TRIGGERS használatával ALTER DATABASE.

A rekurzív triggerek a következő típusú rekurziót teszik lehetővé:

  • Közvetett rekurzió: Közvetett rekurzió esetén egy alkalmazásfrissítési tábla T1. Ez aktiválja a tábla TR1frissítését.T2 Az eseményindító T2 ezután elindítja és frissíti a táblát T1.

  • Közvetlen rekurzió: A közvetlen rekurzióban az alkalmazás frissíti a táblát T1. Ez aktiválja a tábla TR1frissítését.T1 Mivel a tábla T1 frissült, újra aktiválja TR1 a tüzet, és így tovább.

Az alábbi példa a közvetett és a közvetlen eseményindítók rekurzióját használja, feltételezve, TR1 hogy két frissítési eseményindító és TR2egy tábla T1van definiálva. A trigger TR1 rekurzív módon frissíti a táblát T1 . Egy UPDATE utasítás minden TR1 alkalommal lefut TR2 . Emellett a triggerek elindítása TR1 (rekurzív módon) és TR1.TR2 Egy adott eseményindító beszúrt és törölt táblái olyan sorokat tartalmaznak, amelyek csak az UPDATE eseményindítót meghívó utasításnak felelnek meg.

Megjegyzés:

Az előző viselkedés csak akkor fordul elő, ha a RECURSIVE_TRIGGERS beállítás engedélyezve van a használatával ALTER DATABASE. Nincs definiált sorrend, amelyben egy adott eseményhez definiált több eseményindító futna. Minden eseményindítónak önállónak kell lennie.

A beállítás letiltása csak a RECURSIVE_TRIGGERS közvetlen rekurziókat akadályozza meg. A közvetett rekurzió letiltásához állítsa a beágyazott eseményindítók kiszolgálójának beállítását 0-ra a használatával sp_configure.

Ha az eseményindítók bármelyike végrehajt egy eseményindítót ROLLBACK TRANSACTION, függetlenül a beágyazási szinttől, a rendszer nem futtat több eseményindítót.

Beágyazott eseményindítók

Az eseményindítókat legfeljebb 32 szintre ágyazhatja. Ha egy eseményindító módosít egy táblát, amelyen egy másik eseményindító is található, a második eseményindító aktiválódik, majd meghívhat egy harmadik eseményindítót, és így tovább. Ha a lánc bármely eseményindítója végtelen hurkot állít be, a beágyazási szint túllépi a műveletet, és a trigger megszakad. Ha egy Transact-SQL eseményindító egy CLR-rutinra, típusra vagy összesítésre hivatkozva indít el felügyelt kódot, ez a hivatkozás egy szintnek számít a 32 szintű beágyazási korláttal szemben. A felügyelt kódból meghívott metódusok nem számítanak bele ebbe a korlátba.

A beágyazott eseményindítók letiltásához állítsa a beágyazott eseményindítók beállítást sp_configure 0 (ki) értékre. Az alapértelmezett konfiguráció támogatja a beágyazott eseményindítókat. Ha a beágyazott eseményindítók ki vannak kapcsolva, a rekurzív triggerek is le vannak tiltva, annak ellenére, hogy a RECURSIVE_TRIGGERS beállítás a használatával ALTER DATABASEvan beállítva.

Az eseményindítóba ágyazott AFTER első INSTEAD OF eseményindító akkor is aktiválódik, ha a beágyazott eseményindítók kiszolgálókonfigurációs beállítása 0. Ebben a beállításban azonban a későbbi AFTER eseményindítók nem aktiválnak. Tekintse át az alkalmazásokat beágyazott eseményindítókhoz, és állapítsa meg, hogy az alkalmazások betartják-e az üzleti szabályokat, amikor a beágyazott triggerek kiszolgálókonfigurációs beállítása 0. Ha nem, végezze el a megfelelő módosításokat.

Halasztott névfeloldás

Az SQL Server lehetővé teszi, hogy Transact-SQL tárolt eljárások, eseményindítók, függvények és kötegek fordításkor nem létező táblákra hivatkozzon. Ezt a képességet halasztott névfeloldásnak nevezzük.

Engedélyek

DML-eseményindító létrehozásához engedélyre van szükség ALTER azon a táblán vagy nézeten, amelyen az eseményindító létrejön.

Ha kiszolgálóhatókörrel (ON ALL SERVER) vagy bejelentkezési eseményindítóval szeretne DDL-eseményindítót létrehozni, engedélyre van szükség CONTROL SERVER a kiszolgálón. DDL-eseményindító adatbázis-hatókörrel (ON DATABASE) való létrehozásához engedély szükséges ALTER ANY DATABASE DDL TRIGGER az aktuális adatbázisban.

Példák

Egy. DML-eseményindító használata emlékeztető üzenettel

A következő DML trigger üzenetet nyomtat a kliensnek, amikor valaki megpróbál adatokat hozzáadni vagy megváltoztatni az Customer AdventureWorks2025 adatbázis táblázatában.

CREATE TRIGGER reminder1
ON Sales.Customer
AFTER INSERT, UPDATE
AS RAISERROR ('Notify Customer Relations', 16, 10);
GO

B. DML-eseményindító használata emlékeztető e-mail üzenettel

Az alábbi példa e-mailt küld egy adott személynek (MaryM) a Customer tábla változásakor.

CREATE TRIGGER reminder2
ON Sales.Customer
AFTER INSERT, UPDATE, DELETE
AS
    EXECUTE msdb.dbo.sp_send_dbmail
        @profile_name = 'AdventureWorks2022 Administrator',
        @recipients = 'danw@Adventure-Works.com',
        @body = 'Don''t forget to print a report for the sales force.',
        @subject = 'Reminder';
GO

C. DML AFTER-eseményindító használata a PurchaseOrderHeader és a Vendor táblák közötti üzleti szabály kikényszerítéséhez

Mivel CHECK a kényszerek csak azokra az oszlopokra hivatkoznak, amelyeken az oszlopszintű vagy táblaszintű korlátozás van definiálva, minden táblaközi kényszert (ebben az esetben üzleti szabályokat) eseményindítóként kell meghatároznia.

Az alábbi példa létrehoz egy DML-eseményindítót az AdventureWorks2025 adatbázisban. Ez az eseményindító ellenőrzi, hogy a szállító hitelminősítése megfelelő-e (nem 5), ha új beszerzési rendelést próbál beszúrni a PurchaseOrderHeader táblába. A szállító hitelminősítésének lekéréséhez hivatkozni kell a Vendor táblára. Ha a hitelminősítés túl alacsony, megjelenik egy üzenet, és a beszúrás nem történik meg.

USE AdventureWorks2022;
GO

IF OBJECT_ID('Purchasing.LowCredit', 'TR') IS NOT NULL
    DROP TRIGGER Purchasing.LowCredit;
GO

-- This trigger prevents a row from being inserted in the Purchasing.PurchaseOrderHeader table
-- when the credit rating of the specified vendor is set to 5 (below average).
CREATE TRIGGER Purchasing.LowCredit
ON Purchasing.PurchaseOrderHeader
AFTER INSERT
AS
    IF (ROWCOUNT_BIG() = 0)
    RETURN;
    IF EXISTS (SELECT 1
        FROM inserted AS i
        INNER JOIN Purchasing.Vendor AS v
            ON v.BusinessEntityID = i.VendorID
            WHERE v.CreditRating = 5)
BEGIN
    RAISERROR ('A vendor''s credit rating is too low to accept new purchase orders.', 16, 1);
    ROLLBACK;
    RETURN;
END
GO

-- This statement attempts to insert a row into the PurchaseOrderHeader table  
-- for a vendor that has a below average credit rating.  
-- The AFTER INSERT trigger is fired and the INSERT transaction is rolled back.  

INSERT INTO Purchasing.PurchaseOrderHeader (RevisionNumber, Status, EmployeeID,
    VendorID, ShipMethodID, OrderDate, ShipDate, SubTotal, TaxAmt, Freight)
VALUES (2, 3, 261, 1652, 4, GETDATE(), GETDATE(), 44594.55, 3567.564, 1114.8638);
GO

D. Adatbázis-hatókörű DDL-eseményindító használata

Az alábbi példa egy DDL-eseményindítót használ az adatbázis szinonimáinak elvetésének megakadályozására.

CREATE TRIGGER safety
    ON DATABASE
    FOR DROP_SYNONYM
    AS IF (@@ROWCOUNT = 0)
           RETURN;
       RAISERROR ('You must disable Trigger "safety" to remove synonyms!', 10, 1);
       ROLLBACK;
GO

DROP TRIGGER safety
    ON DATABASE;
GO

E. Kiszolgáló hatókörű DDL-eseményindító használata

Az alábbi példa egy DDL-eseményindítót használ egy üzenet nyomtatásához, ha az aktuális kiszolgálópéldányon bármilyen CREATE DATABASE esemény történik, és a EVENTDATA függvény használatával lekéri a megfelelő Transact-SQL utasítás szövegét. A DDL-eseményindítókban használt EVENTDATA további példákért lásd az EVENTDATA függvény használatát.

CREATE TRIGGER ddl_trig_database
    ON ALL SERVER
    FOR CREATE_DATABASE
    AS PRINT 'Database Created.';
       SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'nvarchar(max)');
GO

DROP TRIGGER ddl_trig_database
    ON ALL SERVER;
GO

F. Bejelentkezési eseményindító használata

Az alábbi bejelentkezési eseményindító-példa tagadja, hogy a bejelentkezés tagjaként próbálnak bejelentkezni az login_test SQL Serverbe, ha már három felhasználói munkamenet fut a bejelentkezés alatt. Váltson <password> erős jelszóra.

USE master;
GO

CREATE LOGIN login_test
    WITH PASSWORD = '<password>' MUST_CHANGE, CHECK_EXPIRATION = ON;
GO

GRANT VIEW SERVER STATE TO login_test;
GO

CREATE TRIGGER connection_limit_trigger
    ON ALL SERVER
    WITH EXECUTE AS 'login_test'
    FOR LOGON
    AS BEGIN
           IF ORIGINAL_LOGIN() = 'login_test'
              AND (SELECT COUNT(*)
                   FROM sys.dm_exec_sessions
                   WHERE is_user_process = 1
                         AND original_login_name = 'login_test') > 3
               ROLLBACK;
       END

G. Az eseményindítót kiváltó események megtekintése

Az alábbi példa lekérdezi a és sys.triggers a sys.trigger_events katalógus nézeteit, hogy megállapítsa, melyik Transact-SQL nyelvi események aktiválják a triggertsafety. Az eseményindító a safetyD példában jön létre . Használjon adatbázis-hatókörű DDL-eseményindítót.

SELECT TE.*
FROM sys.trigger_events AS TE
     INNER JOIN sys.triggers AS T
         ON T.object_id = TE.object_id
WHERE T.parent_class = 0
      AND T.name = 'safety';
GO