sql >> Database >  >> RDS >> Sqlserver

SQL Server-triggers - Deel 2 DDL- en LOGON-triggers

In SQL Server zijn triggers database-objecten die worden uitgevoerd wanneer er een triggergebeurtenis plaatsvindt op de database of server. Triggers spelen een sleutelrol bij het bereiken van zakelijke vereisten, zoals het waarschuwen van gerichte mensen op basis van een bereikte toestand, het starten van een baan of andere activiteiten. In het vorige artikel over DML-triggers hebben we het gehad over triggers, typen triggers en verschillende trigger-opties die beschikbaar zijn voor DML-triggers. In dit artikel zullen we SQL DDL- en LOGON-triggers onderzoeken.

DDL-triggers

DDL-triggers kunnen worden geactiveerd voor een verscheidenheid aan Server- of Database Scoped-gebeurtenissen, waaronder zowel DDL- als DCL-opdrachten. DDL staat voor Data Definition Language die wordt gebruikt om objecten te CREATE, ALTER, DROP en DCL staat voor Data Control Language-statements zoals GRANT, DENY en REVOKE-opdrachten. Hieronder staan ​​de kenmerken van SQL DDL-triggers.

  1. DDL-triggers kunnen worden gemaakt op databaseniveau of serverinstantieniveau voor een breed scala aan DDL-bewerkingen of DDL-achtige bewerkingen, b.v. DCL-opdrachten.
  2. DDL-triggers kunnen alleen worden aangeroepen of geactiveerd als een FOR- of AFTER-triggertype. SQL Server ondersteunt geen INSTEAD OF DDL Trigger en we kunnen zien hoe we sommige DDL-bewerkingen kunnen voorkomen via DDL Triggers.
  3. SQL Server heeft ingebouwde functies zoals EVENTDATA() en IS_MEMBER() voor gebruik binnen DDL-triggers om meer informatie over de triggergebeurtenissen te verkrijgen.
      De functie
    1. EVENTDATA() retourneert volledige details over database- of serverbereikgebeurtenissen in XML-indeling binnen het bereik van de database- of serverbereik DDL-trigger of aanmeldingstriggers. De functie EVENTDATA() retourneert de volledige gebeurtenisdetails voor de sessie die de DDL- of aanmeldingsactiviteiten uitvoert. EVENTDATA() retourneert de onderstaande details
      • EventType – Type van de gebeurtenis die de DDL-trigger activeert die beschikbaar is in de tabel sys.trigger_event_types.
      • PostTime – Tijdstip waarop de gebeurtenis is geactiveerd of gepost.
      • SPID – Sessie-ID van het evenement.
      • Servernaam – SQL Server-instantienaam waarin de gebeurtenis is geactiveerd.
      • LoginName – SQL Server-aanmeldingsnaam die de gebeurtenis heeft uitgevoerd.
      • Gebruikersnaam – gebruikersnaam van de login die standaard dbo is.
      • DatabaseName – Databasenaam waaronder de DDL-trigger is geactiveerd.
      • SchemaName – Schemanaam van het object dat werd beïnvloed.
      • ObjectName – Objectnaam die is getroffen.
      • ObjectType – Type SQL Server-object zoals tabel, weergave, opgeslagen procedure.
      • TSQLCommand – T-SQL-script dat werd uitgevoerd door een gebruiker die de DDL-trigger aanriep.
      • SetOptions - SET-opties die door de gebruiker of client worden gebruikt, zoals SSMS terwijl de TSQL-opdracht werd uitgevoerd.
      • CommandText – Werkelijke DDL- of DCL-instructies met de DDL-gebeurtenis gespecificeerd in de tabel sys.trigger_event_types.
    2. IS_MEMBER() functie retourneert of de huidige gebruiker lid is van de Windows-groep of SQL Server Database-rol of niet.
  4. Systeem DMV sys.triggers slaat de lijst op van alle triggers met databasebereik. We kunnen de onderstaande query gebruiken om de details van alle DDL-triggers met databasebereik op te halen.
SELECT * 
FROM sys.triggers
WHERE type = 'TR';
  1. Systeem DMV sys.server_triggers slaat de lijst op van alle Server-scoped triggers en we kunnen de onderstaande query gebruiken om de details over alle Server-scoped DDL-triggers op te halen.
SELECT * 
FROM sys.server_triggers;
  1. DDL-triggerdefinities kunnen worden bekeken als de trigger niet is versleuteld met een van de onderstaande opties van sys.sql_modules of met de functie OBJECT_DEFINITION() of met de sp_helptext opgeslagen procedure.
SELECT OBJECT_SCHEMA_NAME(object_id, db_id()) Schema_name, OBJECT_NAME(object_id) Trigger_Name, definition
FROM sys.sql_modules  
WHERE object_id = OBJECT_ID(<trigger_name>);   

SELECT OBJECT_DEFINITION (OBJECT_ID(<trigger_name>)) AS ObjectDefinition; 

EXEC sp_helptext '<trigger_name>';
  1. Alle mogelijke DDL-gebeurtenissen zijn beschikbaar in de tabel sys.trigger_event_types en kunnen worden bekeken met de onderstaande query.
SELECT *
FROM sys.trigger_event_types;

De syntaxis van een DDL-trigger is:

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

DDL-trigger met databasebereik maken

Laten we een Database Scoped-trigger maken om alle tabelcreaties bij te houden en in te loggen op een Logging-tabel met de naam Track_DDL_Changes met behulp van het onderstaande script.

CREATE TABLE Track_DDL_Changes (EventData xml, PostDtm datetime)
GO
CREATE TRIGGER TR_D_CREATETABLE
ON DATABASE
FOR CREATE_TABLE
AS
BEGIN
	INSERT INTO Track_DDL_Changes
	SELECT EVENTDATA(),GETDATE()
END
GO

Laten we een nieuwe tabel maken met de naam trigger_test en controleren of de CREATE TABLE-gebeurtenis is gecontroleerd of niet met behulp van het onderstaande script.

CREATE TABLE Trigger_Test ( a int, b datetime);

Als u de gegevens uit de tabel Track_DDL_Changes selecteert, wordt weergegeven dat de bovenstaande CREATE_TABLE-gebeurtenis met succes is vastgelegd, zoals hieronder wordt weergegeven:

Als u op de EventData-waarde klikt, wordt de XML EVENTDATA()-waarde geopend in een nieuw venster, zoals hieronder weergegeven.

We kunnen de volledige details over de triggergebeurtenis verifiëren via de EVENTDATA()-functie en daarom zou de EVENTDATA()-functie een belangrijke rol spelen voor alle DDL- of LOGON-triggers.

We kunnen onze DDL-trigger verder verbeteren met behulp van de EVENTDATA()-functie en XML-parsing en voorkomen dat iemand een tabel in de testdatabase maakt met behulp van het onderstaande script:

CREATE TRIGGER TR_D_PREVENT_CREATETABLE
ON DATABASE
FOR CREATE_TABLE
AS
BEGIN
   SELECT EVENTDATA().value  
        ('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')  
   RAISERROR ('Creation of New tables restricted in this database, Kindly contact DBA.', 16, 1)   
   ROLLBACK  
END
GO

Creëren van Database Scoped trigger is met succes voltooid en laten we verifiëren door een andere tabel te maken met behulp van het onderstaande script.

CREATE TABLE Trigger_Test1 (a int, b datetime);

De trigger heeft ons verhinderd om nieuwe tabellen in deze database te maken en heeft ook een zinvolle boodschap voor gebruikers achtergelaten. We kunnen op dezelfde manier alle andere DDL- of Server-scope-gebeurtenissen afhandelen om aan de vereisten te voldoen.

Om DDL-trigger met databasebereik te laten vallen, moeten we de onderstaande syntaxis gebruiken:

DROP TRIGGER <trigger_name> ON DATABASE;

En om de trigger te laten vallen die we zojuist hebben gemaakt, zou het script zijn

DROP TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;

Om de DDL-triggers met databasebereik in SSMS te bekijken, vouwt u Testdatabase -> Programmeerbaarheid -> Databasetriggers uit, zoals hieronder weergegeven.

Net als bij SQL DML-triggers, kunnen DDL-triggers worden verwijderd, uitgeschakeld of ingeschakeld door met de rechtermuisknop op de triggernaam te klikken, zoals hieronder wordt weergegeven.

Via T-SQL kunnen we DDL-trigger met database-scope laten vallen of uitschakelen of inschakelen met behulp van de onderstaande syntaxis:

-- DROP Database scoped DDL Trigger
DROP TRIGGER <trigger_name> ON DATABASE;
-- Enable Database scoped DDL Trigger
ENABLE TRIGGER <trigger_name> ON DATABASE;
-- Disable Database scoped DDL Trigger
DISABLE TRIGGER <trigger_name> ON DATABASE;

Om de trigger die we hebben gemaakt uit te schakelen, moeten we mogelijk het onderstaande script gebruiken.

-- DROP Database scoped DDL Trigger
DROP TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;
-- Enable Database scoped DDL Trigger
ENABLE TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;
-- Disable Database scoped DDL Trigger
DISABLE TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;

Server Scoped DDL-trigger maken

DDL-trigger met serverbereik volgt dezelfde syntaxis als DDL-trigger voor databasebereik, behalve dat de gebeurtenissen worden gebaseerd op het bereik van de server.

Laten we proberen een DDL-trigger met serverbereik te maken om te voorkomen dat een gebruiker een nieuwe database op deze serverinstantie maakt met behulp van het onderstaande script.

CREATE TRIGGER TR_S_PREVENT_CREATEDATABASE
ON ALL SERVER
FOR CREATE_DATABASE
AS
BEGIN
   SELECT EVENTDATA().value  
        ('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')  
   RAISERROR ('Creation of New Databases restricted in this Instance, Kindly contact DBA.', 16, 1)   
   ROLLBACK  
END
GO

Wanneer we proberen een nieuwe database aan te maken met behulp van de onderstaande opdracht, krijgen we een foutmelding zoals hieronder weergegeven.

CREATE DATABASE DATABASE_TEST;

In SSMS heeft de server DDL-triggers onder Triggers in het gedeelte Serverobjecten ingedeeld, zoals hieronder weergegeven.

We kunnen de Server-scoped DDL-trigger laten vallen, uitschakelen of inschakelen door simpelweg met de rechtermuisknop op de Server Scoped DDL-trigger te klikken, zoals hieronder weergegeven.

Via T-SQL kunnen we laten vallen of uitschakelen of inschakelen met behulp van de onderstaande opdracht.

-- DROP Server scoped DDL Trigger
DROP TRIGGER TR_S_PREVENT_CREATEDATABASE ON ALL SERVER;
-- Disable Server scoped DDL Trigger
DISABLE TRIGGER TR_S_PREVENT_CREATEDATABASE ON ALL SERVER;
-- Enable Server scoped DDL Trigger
ENABLE TRIGGER TR_S_PREVENT_CREATEDATABASE ON ALL SERVER;

Het doel van DDL-triggers

  1. Om alle DDL-gebeurtenissen te controleren die plaatsvinden op database- of serverniveau.
  2. Om te voorkomen dat er DDL-gebeurtenissen plaatsvinden op database- of serverniveau.
  3. Om te waarschuwen wanneer er DDL-gebeurtenissen plaatsvinden op database- of serverniveau.

Aanmeldingstriggers

Aanmeldingstriggers zoals de naam aangeeft, worden uitgevoerd voor LOGON-gebeurtenissen in SQL Server. Zodra de verificatiefase is voltooid voor een aanmeldingsgebeurtenis, wordt het LOGON Trigger-script uitgevoerd naast de aanmeldingsactiviteit. Als de aanmelding niet met succes is geverifieerd, worden LOGON-triggers niet geactiveerd. Aanmeldingstriggers worden vermeld in SSMS onder het gedeelte Triggers van Serverobjecten. De syntaxis van een LOGON-trigger is als volgt:

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

Creëer triggers

Laten we een eenvoudige LOGON-trigger maken om meer informatie over de LOGON-gebeurtenis vast te leggen van de EVENTDATA()-functie, zoals hieronder weergegeven.

CREATE TABLE Track_LOGON_EVENTS (EventData xml, PostDtm datetime)
GO
CREATE TRIGGER TR_LOGON
ON ALL SERVER
FOR LOGON
AS
BEGIN
	INSERT INTO Track_LOGON_EVENTS
	SELECT EVENTDATA(),GETDATE();
END
GO

De bovenstaande LOGON-trigger legt alle details vast over een inlogactiviteit die lijkt op wat we hebben opgemerkt tijdens het gebruik van de EVENTDATA()-functie in DDL Trigger. We moeten voorzichtig zijn bij het plannen om LOGON-triggers te gebruiken, alsof er logische fouten in de trigger zitten, het zou niemand of de meeste gebruikers toestaan ​​om verbinding te maken met het exemplaar van SQL Server.

Om LOGON-triggers te DROP, in- of uit te schakelen, kunnen we het onderstaande script gebruiken.

-- DROP LOGON Trigger
DROP TRIGGER TR_LOGON ON ALL SERVER;
-- Disable LOGON Trigger
DISABLE TRIGGER TR_LOGON ON ALL SERVER;
-- Enable LOGON Trigger
ENABLE TRIGGER TR_LOGON ON ALL SERVER;

Het doel van LOGON Triggers

  1. Om alle LOGON-gebeurtenissen op de server te controleren.
  2. Om te voorkomen dat er LOGON-gebeurtenissen plaatsvinden op de server
  3. Om te waarschuwen wanneer er LOGON-gebeurtenissen plaatsvinden op de server.

Triggereigenschappen

sp_settriggerorder

sp_settriggerorder wordt gebruikt om de volgorde van triggeruitvoering alleen voor de eerste en laatste triggers te definiëren. Als er meer dan 2 DML-triggers in een tabel zijn, laten we zeggen 5 DML-triggers, dan kunnen we de eerste DML-trigger en de laatste DML-trigger definiëren, maar kunnen we de volgorde van de middelste 3 triggers niet definiëren.

Opmerking: Het instellen van de EERSTE of LAATSTE optie is specifiek voor een bepaalde gebeurteniscategorie voor DML-triggers. In een tabel met 3 INSERT-triggers kunnen we bijvoorbeeld definiëren welke INSERT-trigger EERST is en welke INSERT-trigger LAATSTE is. Als je 3 triggers op een tafel hebt, zoals INSERT, UPDATE en DELETE, dan is het niet nodig om de triggervolgorde in te stellen.

De syntaxis voor het instellen van de triggervolgorde zou als volgt zijn:

exec sp_settriggerorder @triggername = '<trigger_schema_name.trigger_name>' 
    , @order = 'FIRST' | 'LAST'   
    , @stmttype = '<trigger event type>'   
    , @namespace = 'DATABASE' | 'SERVER' | 'NULL'

Voor DDL-triggers kunnen we de eerste en laatste Server Scoped-triggers definiëren en vervolgens de eerste en de laatste Database Scoped-triggers definiëren. Als we bijvoorbeeld 5 Server Scoped-triggers en 5 Database Scoped-triggers hebben, kan de volgorde als volgt worden gedefinieerd:

  1. Eerste trigger voor Server Scoped DDL-trigger
  2. 3 andere DDL-triggers met serverbereik in willekeurige volgorde
  3. Laatste trigger voor Server Scoped DDL-trigger.
  4. Eerste trigger voor DDL-trigger met databasebereik (één per database)
  5. 3 andere DDL-triggers met databasebereik in willekeurige volgorde
  6. Laatste trigger voor Database Scoped DDL-trigger.

Met betrekking tot het instellen van de eerste of de laatste optie, kunnen de DDL-triggers met databasebereik worden besteld binnen de database en de DDL-triggers met serverbereik op Instance-niveau.

Hoewel SQL Server ons in staat stelt om veel triggers op een tafel te maken, wordt aanbevolen om de vereisten van de trigger zorgvuldig te analyseren voor beter onderhoud en probleemoplossing.

Recursieve triggers

SQL Server ondersteunt ook het recursief aanroepen van triggers voor DML-triggers. Recursieve triggers kunnen worden geclassificeerd als direct of indirect, zoals hieronder weergegeven.

Directe recursieve triggers – Gebruiker of toepassing werkt een record in tabel A bij. UPDATE Trigger A in tabel A wordt geactiveerd en werkt tabel A opnieuw bij. Aangezien het record in Tabel A is bijgewerkt via Trigger, zal het opnieuw UPDATE Trigger A aanroepen en dit zal recursief gebeuren.

Laten we een Direct Recursive Triggers op de Sales-tabel maken met behulp van het onderstaande script:

CREATE TRIGGER TR_UPD_Recursive_Sales ON Sales
FOR UPDATE 
AS
BEGIN
  UPDATE Sales 
  SET SalesDate = GETDATE() 
  WHERE SalesId = (SELECT SalesId FROM Inserted)
END
GO

Voer het onderstaande script uit:

UPDATE Sales 
SET SalesDate = GETDATE() 
WHERE SalesId = 3;

Indirecte recursieve triggers – Gebruiker of toepassing werkt een record bij in Tabel A. De UPDATE-trigger A in Tabel A wordt geactiveerd en werkt een record bij in Tabel B. Als Tabel B een UPDATE-trigger heeft om records terug bij te werken naar Tabel A, wordt de UPDATE-trigger in Tabel A die recursief zal gebeuren.

Laten we een indirecte recursieve trigger maken op IDR_Test1- en IDR_Test2-tabellen met behulp van het onderstaande script:

DROP TABLE IDR_Test1
DROP TABLE IDR_Test2

CREATE TABLE IDR_Test1 (PK int NOT NULL);
GO
INSERT INTO IDR_Test1 
values (10),(20)
GO
CREATE TABLE IDR_Test2 (PK int NOT NULL);
GO
INSERT INTO IDR_Test2
values (10),(20)
GO

CREATE TRIGGER TR_IDR_Test1
ON IDR_Test1
FOR UPDATE 
AS
BEGIN
	UPDATE IDR_Test2
	SET PK = 30
	WHERE PK IN (SELECT PK FROM inserted);
END
GO
 
CREATE TRIGGER TR_Temp2
ON IDR_Test2
FOR UPDATE 
AS
BEGIN
	UPDATE IDR_Test1
	SET PK = 30
	WHERE PK IN (SELECT PK FROM inserted);
END
GO

Voer het onderstaande script uit:

UPDATE IDR_Test1
SET PK = 1
WHERE PK = 10;

Om dit soort recursieve triggers op databaseniveau te voorkomen, heeft SQL Server een optie genaamd RECURSIVE_TRIGGERS op elk databaseniveau om de recursieve trigger-triggering te verbreken. De optie Recursieve trigger is standaard ingesteld op False voor een database. Schakel alleen in zoals vereist na zorgvuldige afweging van de prestatie-impact of betrokken gegevenswijzigingen.

Klik in SSMS met de rechtermuisknop op onze testdatabase -> Kies Eigenschappen -> Klik op Opties en scrol omlaag om te zien dat de optie Recursieve triggers is ingeschakeld of niet, zoals hieronder wordt weergegeven. Voor Test Database is deze ingesteld op False, aangezien False de standaardwaarde is voor de optie Recursieve triggers. Als u de optie Recursieve triggers voor een specifieke database wilt inschakelen, klikt u op de vervolgkeuzelijst, wijzigt u deze in True en klikt u op OK.

Via T-SQL kunnen we de Recursive Trigger-optie van de testdatabase verifiëren door de kolom is_recursive_triggers_on van sys.databases DMV te controleren, zoals hieronder weergegeven.

select name, is_recursive_triggers_on
from sys.databases
where name = 'test'

Om de Recursieve triggers-optie voor een database te wijzigen (Test in mijn voorbeeld), kunnen we het onderstaande script uitvoeren.

ALTER DATABASE [Test] SET RECURSIVE_TRIGGERS ON WITH NO_WAIT
GO

Om het weer uit te schakelen naar de valse status (standaardstatus) voor een database (Test in mijn voorbeeld), voert u het onderstaande script uit.

ALTER DATABASE [Test] SET RECURSIVE_TRIGGERS OFF WITH NO_WAIT
GO

Geneste triggers

Recursieve triggers zijn een klassiek voorbeeld van geneste triggers, maar er kunnen weinig andere gevallen zijn die resulteren in nesting van meerdere triggers. Met SQL Server kunnen triggers worden genest tot maximaal 32 niveaus en elke trigger die dat nestingniveau overschrijdt, wordt geannuleerd door SQL Server. SQL Server heeft een instantiebrede configuratie om de optie Geneste triggers uit te schakelen. Houd er rekening mee dat het nesten van SQL Server-triggers met behulp van CLR-code of beheerde code niet onder de limiet van 32 niveaus valt, aangezien dit buiten het bereik van de SQL Server valt. De optie voor geneste triggers wordt standaard ingeschakeld voor alle SQL Server-instanties en we kunnen deze desgewenst uitschakelen.

We kunnen controleren of de optie voor geneste triggers is ingeschakeld op instantieniveau in SSMS door de onderstaande stappen te volgen:

Klik met de rechtermuisknop op Server -> Kies Eigenschappen -> Klik op Geavanceerd

Als u de optie voor geneste triggers wilt uitschakelen of uitschakelen, klikt u op de vervolgkeuzelijst en wijzigt u deze in False en klikt u op OK .

Via T-SQL kunnen we controleren of de optie Geneste triggers is ingeschakeld door de kolom value_in_use in sys.configurations DMV te controleren op configuratienaam voor geneste triggers.

Om deze optie uit te schakelen, moeten we de sp_configure de door het systeem opgeslagen procedure gebruiken, zoals hieronder getoond:

EXEC sp_configure 'nested triggers', 0;  
GO  
RECONFIGURE;  
GO  

Binnen alle DML- of DDL-triggers, om het huidige niveau van nesting te vinden, heeft SQL Server een ingebouwde functie met de naam TRIGGER_NESTLEVEL om het aantal triggers te retourneren dat is uitgevoerd voor de huidige instructie die de trigger heeft geactiveerd, inclusief zichzelf. De syntaxis van de TRIGGER_NESTLEVEL-functie zou zijn:

SELECT TRIGGER_NESTLEVEL ( object_id, <trigger_type> , <trigger_event_category> )

Waar object_id het object-ID van de trigger is, is trigger_type AFTER voor AFTER trigger en IOT voor INSTEAD OF trigger en trigger_event_category is DML of DDL.

Als we bijvoorbeeld alleen nestniveau tot 10 moeten toestaan ​​en de fout na 10 niveaus moeten verhogen, dan kunnen we dit doen op testtrigger zoals hier:

IF ((SELECT TRIGGER_NESTLEVEL(OBJECT_ID('test_trigger'), 'AFTER’, 'DML’)) > 10)  
   RAISERROR ('Trigger test_trigger nested more than 10 levels.',16, -1)   

ENCRYPTIE

Om de triggerlogica of -definitie te coderen, kan de WITH ENCRYPTION-optie worden gebruikt in de triggerdefinitie, vergelijkbaar met alle andere SQL Server-objecten.

EXECUTE AS-clausule

Om de trigger uit te voeren met een specifieke beveiligingscontext, kan de EXECUTE AS-component worden gebruikt in de triggerdefinitie.

NIET VOOR REPLICATIE

Om vast te stellen dat de DML-trigger niet moet worden aangeroepen terwijl deze wordt uitgevoerd via replicatiewijzigingen, wordt de eigenschap NOT FOR REPLICATION ingesteld voor alle objecten in de abonneedatabase.

Conclusie

Bedankt voor het doornemen van het krachtige artikel over DDL-triggers en aanmeldingstriggers, waarin we het doel van DDL- en aanmeldingstriggers hebben begrepen, hoe u deze triggers kunt maken of verwijderen, uitschakelen of inschakelen, samen met het gebruik van de functie EVENTDATA() voor het volgen van DDL- of aanmeldingsactiviteiten. Daarnaast hebben we geleerd hoe we de uitvoeringsvolgorde van meerdere SQL DML- of DDL-triggers samen met recursieve en geneste triggers in detail kunnen instellen en hoe we zorgvuldig omgaan met recursieve of geneste triggers.


  1. Gebruik OBJECTPROPERTY() om erachter te komen of een tabel een systeemtabel is in SQL Server

  2. Exporteer SQL-querygegevens naar Excel

  3. GI 19c RPM Package Manager-database

  4. Hoe voeg ik de identiteitseigenschap toe aan een bestaande kolom in SQL Server?