Sometimes the data in our database tables will be deleted inexplicably. I don't know if it is a business problem or hacked, so we want to stop this at the database operation level and record the operation log at the same time. We can use triggers to achieve this. This requirement, test data:
--Test Data if not object_id(N'T') is null drop table T Go Create table T([ID] int,[姓名] nvarchar(22)) Insert T select 1,N'Zhang San' union all select 2,N'Li Si' union all select 3,N'Wang Wu' GO -- end of test data
New log table:
CREATE TABLE TBLOG ( ID INT NOT NULL IDENTITY(1, 1) , EVTIME DATETIME NOT NULL DEFAULT ( GETDATE() ) , -- access time [SQL] VARCHAR(300) , -- SQL statement to execute USERID VARCHAR(128) NOT NULL DEFAULT ( SUSER_SNAME() ) , -- which SQL login user to use when connecting HOSTNAME VARCHAR(128) NOT NULL DEFAULT ( HOST_NAME() ) , -- the client's machine name LOGINID VARCHAR(128), -- the login user of the client (OS user) APPNAME VARCHAR(128) NOT NULL DEFAULT ( APP_NAME()) -- is it executed from the query analyzer, or from the application )
New trigger:
CREATE TRIGGER TR_TBTEST ON T FOR DELETE AS RAISERROR('error',16,8) ROLLBACK TRAN --SQL CREATE TABLE #T ( EVENTTYPE VARCHAR(20) , PARAMETERS INT , EVENTINFO VARCHAR(300) ) DECLARE @SPID VARCHAR(20) SET @SPID = CAST(@@SPID AS VARCHAR) INSERT #T EXEC ( 'DBCC INPUTBUFFER (' + @SPID + ')' ) --process information DECLARE @USERID VARCHAR(128) , -- which SQL login user to use when connecting @HOSTNAME VARCHAR(128) , -- the machine name of the client @LOGINID VARCHAR(128) , -- the login user of the client (OS user) @APPNAME VARCHAR(128) -- is it executed from the query analyzer, or from the application SELECT @USERID = LOGINAME , -- which SQL login user to use when connecting @HOSTNAME = HOSTNAME , -- the machine name of the client @LOGINID = NT_USERNAME , -- the login user of the client (OS user) @APPNAME = PROGRAM_NAME -- whether to execute from the query analyzer, or from the application FROM MASTER..SYSPROCESSES WHERE SPID = @@SPID INSERT TBLOG ( SQL , USERID , HOSTNAME , LOGINID , APPNAME ) SELECT EVENTINFO , @USERID , @HOSTNAME , @LOGINID , @APPNAME FROM #T GO
Test removal:
DELETE FROM T WHERE id=1
result:
Query logs and data:
SELECT * FROM TBLOG SELECT * FROM T
result:
The above achieves the function we want to prohibit deleting and adding logs. Of course, we can also apply this to INSERT, UPDATE and other operations.