乱码乱a∨中文字幕,在线免费激情视频,亚洲欧美久久夜夜潮,国产在线网址

  1. <sub id="hjl7n"></sub>

    1. <sub id="hjl7n"></sub>

      <legend id="hjl7n"></legend>

      當(dāng)前位置:首頁 >  站長 >  數(shù)據(jù)庫 >  正文

      SQL Server 添加Delete操作回滾日志方式

       2021-01-19 17:05  來源: 腳本之家   我來投稿 撤稿糾錯

        阿里云優(yōu)惠券 先領(lǐng)券再下單

      這篇文章主要介紹了SQL Server 添加Delete操作回滾日志方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

      我們在操作表的時候難免會遇到誤刪除,或者刪掉的數(shù)據(jù)還想恢復(fù)的情況。

      也許細心的朋友會用begin tran rollback/commit 這種事務(wù)來避免出現(xiàn)失誤,但這并不是最保險的。

      如果提交了事物發(fā)現(xiàn)刪錯了或者忘記提交從而導(dǎo)致表被鎖,這些問題總是不可避免的。

      廢話不多說了,下面直接進入正題,通過觸發(fā)器記錄刪除日志,避免誤刪除帶來的尷尬。

      下面這段sql粘過去直接運行,建立一個存儲過程:

      CREATE PROCEDURE [dbo].[SP_DELETE_LOG]
      @TABLENAME VARCHAR(50)
      AS
      BEGIN
      SET NOCOUNT ON;
      IF NOT EXISTS(SELECT * FROM sys.tables WHERE NAME = @TABLENAME AND TYPE = 'U' )
      BEGIN
      PRINT'ERROR:not exist table '+@TABLENAME
      RETURN
      END
      IF (@TABLENAME LIKE'BACKUP_%' OR @TABLENAME='UPDATE_LOG' )
      BEGIN
      --PRINT'ERROR:not exist table '+@TABLENAME
      RETURN
      END
      --================================判斷是否存在 UPDATE_LOG 表============================
      IF NOT EXISTS(SELECT * FROM sys.tables WHERE NAME = 'UPDATE_LOG' AND TYPE = 'U')
      CREATE TABLE UPDATE_LOG
      (
      UpdateGUID VARCHAR(36),
      UpdateTime DATETIME,
      TableName varchar(20),
      UpdateType varchar(6),
      RollBackSQL varchar(1000)
      )
      --=================================判斷是否存在 BACKUP_ 表================================
      IF NOT EXISTS(SELECT * FROM sys.tables WHERE NAME = 'BACKUP_'+@TABLENAME AND TYPE = 'U')
      BEGIN
      --DECLARE @SQL VARCHAR(500)
      --SET @SQL='SELECT TOP 1 NEWID() AS [UpdateGUID],* INTO BACKUP_'+@TABLENAME+' FROM '+ @TABLENAME+'
      -- DELETE FROM BACKUP_'+@TABLENAME
      --SELECT @SQL
      --EXEC(@SQL)
      DECLARE test_Cursor CURSOR FOR
      SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.columns
      WHERE TABLE_NAME=@TABLENAME
      OPEN test_Cursor
      DECLARE @SQLTB NVARCHAR(MAX)=''
      DECLARE @COLUMN_NAME NVARCHAR(50),@DATA_TYPE VARCHAR(20),@CHARACTER_MAXIMUM_LENGTH INT
      FETCH NEXT FROM test_Cursor INTO @COLUMN_NAME,@DATA_TYPE,@CHARACTER_MAXIMUM_LENGTH
      WHILE @@FETCH_STATUS=0
      BEGIN
      SET @SQLTB=@SQLTB+'['+@COLUMN_NAME+'] '+@DATA_TYPE+CASE ISNULL(@CHARACTER_MAXIMUM_LENGTH,0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE'('+CAST(@CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10))+')' END+','
      FETCH NEXT FROM test_Cursor INTO @COLUMN_NAME,@DATA_TYPE,@CHARACTER_MAXIMUM_LENGTH
      END
      SET @SQLTB='CREATE TABLE BACKUP_'+@TABLENAME+' (UpdateGUID varchar(36),'+SUBSTRING(@SQLTB,1,LEN(@SQLTB)-1)+')'
      EXEC (@SQLTB)
      CLOSE test_Cursor
      DEALLOCATE test_Cursor
      END
      --======================================判斷是否存在 DELETE 觸發(fā)器=========================
      IF NOT EXISTS(SELECT * FROM sys.objects WHERE NAME = 'tg_'+@TABLENAME+'_Delete' AND TYPE = 'TR')
      BEGIN
      DECLARE @SQLTR NVARCHAR(MAX)
      SET @SQLTR='
      CREATE TRIGGER tg_'+@TABLENAME+'_Delete
      ON '+@TABLENAME+'
      AFTER delete
      AS
      BEGIN
      SET NOCOUNT ON;
      --==============================獲取GUID==========================================
      DECLARE @NEWID VARCHAR(36)=NEWID()
      --==============================將刪掉的數(shù)據(jù)插入備份表============================
      INSERT INTO [dbo].[BACKUP_'+@TABLENAME+']
      SELECT @NEWID,* FROM deleted
      --==============================記錄日志和回滾操作的SQL===========================
      --*********************生成列名**********************
      DECLARE @COLUMN NVARCHAR(MAX)=''''
      SELECT @COLUMN+='',[''+COLUMN_NAME+'']'' FROM INFORMATION_SCHEMA.columns
      WHERE TABLE_NAME='''+@TABLENAME+'''
      AND COLUMNPROPERTY(OBJECT_ID('''+@TABLENAME+'''),COLUMN_NAME,''IsIdentity'')<>1 --非自增字段
      SET @COLUMN=SUBSTRING(@COLUMN,2,LEN(@COLUMN))
      INSERT INTO [dbo].[UPDATE_LOG]
      SELECT @NEWID,GETDATE(),'''+@TABLENAME+''',''DELETE'',''INSERT INTO '+@TABLENAME+' SELECT ''+@COLUMN+'' FROM BACKUP_'+@TABLENAME+' WHERE UPDATEGUID=''''''+@NEWID+''''''''
      END
      '
      EXEC(@SQLTR)
      END
      END

      接著我們新建一張測試表,并且隨便往表中插入兩組數(shù)據(jù):

      Create table test
      (
      id int,
      name varchar(10),
      msg varchar(10)
      )
      Insert into test
      Select 1,'aa','hahah'
      Union all
      Select 2,'bb','heihei'

      下面執(zhí)行這個SP,在給test表添加回滾日志:

      1EXEC SP_DELETE_LOG 'test'

      細心的你不難發(fā)現(xiàn),這時候數(shù)據(jù)庫里面應(yīng)該會多出兩張表:

      然后我們刪掉一條數(shù)據(jù):

      1DELETE FROM test WHERE id=1

      再查看那兩張表:

      沒錯,這時候日志表里有數(shù)據(jù)了,然后我們把 UPDATE_LOG 表中的 RollBackSQ L這一列對應(yīng)的值copy出來執(zhí)行一下:

      1INSERT INTO test SELECT [id],[name],[msg] FROM BACKUP_test WHERE UPDATEGUID='B0CBBC4F-3432-4D4F-9E17-F17209BF6745'

      別copy我上面這段sql,因為GUID肯定是不一樣的!

      然而,數(shù)據(jù)恢復(fù)了:

      最后,delete日志的介紹就結(jié)束了,唯一的不滿足的是只能作用在Delete 操作,其實UPDATE 操作也同樣需要這樣的回滾日志。

      以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

      來源:腳本之家

      鏈接:https://www.jb51.net/article/204070.htm

      申請創(chuàng)業(yè)報道,分享創(chuàng)業(yè)好點子。點擊此處,共同探討創(chuàng)業(yè)新機遇!

      相關(guān)標(biāo)簽
      sqlserver

      相關(guān)文章

      熱門排行

      信息推薦