有時候我們數(shù)據(jù)庫表中的數(shù)據(jù)會莫名其妙的被刪除,不知道是業(yè)務(wù)問題還是被黑了,所以我們想要在數(shù)據(jù)庫操作層面對此進行制止,同時記錄操作的日志,我們可以利用觸發(fā)器來實現(xiàn)這個需求,測試數(shù)據(jù):
- --測試數(shù)據(jù)
- if not object_id(N'T') is null
- drop table T
- Go
- Create table T([ID] int,[姓名] nvarchar(22))
- Insert T
- select 1,N'張三' union all
- select 2,N'李四' union all
- select 3,N'王五'
- GO
- --測試數(shù)據(jù)結(jié)束
新建日志表:
- CREATE TABLE TBLOG
- (
- ID INT NOT NULL IDENTITY(1, 1) ,
- EVTIME DATETIME NOT NULL DEFAULT ( GETDATE() ) , --訪問時間
- [SQL] VARCHAR(300) , --執(zhí)行的SQL語句
- USERID VARCHAR(128) NOT NULL DEFAULT ( SUSER_SNAME() ) , --連接的時候使用的哪個SQL登陸用戶
- HOSTNAME VARCHAR(128) NOT NULL DEFAULT ( HOST_NAME() ) , --客戶端的機器名
- LOGINID VARCHAR(128), --客戶端的登陸用戶(OS的用戶)
- APPNAME VARCHAR(128)NOT NULL DEFAULT ( APP_NAME()) --是從查詢分析器,還是應(yīng)用程序來執(zhí)行的
- )
新建觸發(fā)器:
- CREATE TRIGGER TR_TBTEST ON T
- FOR DELETE
- AS
- RAISERROR('錯誤',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 + ')'
- )
- --進程信息
- DECLARE @USERID VARCHAR(128) , --連接的時候使用的哪個SQL登陸用戶
- @HOSTNAME VARCHAR(128) , --客戶端的機器名
- @LOGINID VARCHAR(128) , --客戶端的登陸用戶(OS的用戶)
- @APPNAME VARCHAR(128) --是從查詢分析器,還是應(yīng)用程序來執(zhí)行的
- SELECT @USERID = LOGINAME , --連接的時候使用的哪個SQL登陸用戶
- @HOSTNAME = HOSTNAME , --客戶端的機器名
- @LOGINID = NT_USERNAME , --客戶端的登陸用戶(OS的用戶)
- @APPNAME = PROGRAM_NAME --是從查詢分析器,還是應(yīng)用程序來執(zhí)行的
- FROM MASTER..SYSPROCESSES
- WHERE SPID = @@SPID
- INSERT TBLOG
- ( SQL ,
- USERID ,
- HOSTNAME ,
- LOGINID ,
- APPNAME
- )
- SELECT EVENTINFO ,
- @USERID ,
- @HOSTNAME ,
- @LOGINID ,
- @APPNAME
- FROM #T
- GO
測試刪除:
DELETE FROM T WHERE id=1
結(jié)果:
查詢?nèi)罩竞蛿?shù)據(jù)情況:
- SELECT * FROM TBLOG
- SELECT * FROM T
結(jié)果:
以上實現(xiàn)了我們想要的禁止刪除并添加日志的功能,當然我們也可以把這個應(yīng)用到INSERT、UPDATE等操作中。