ApexSQL Log中的Redo Script跟原始SQL不一致问题

摘要:
最近,我遇到了一个错误更新数据的问题。当使用ApexSQLLog挖掘事务日志时,我发现ApexSQLLog生成的RedoScript与原始SQL不同。它们并不相同。这只是逻辑上的等价。如下所示,让我们做一个测试,如下所示。创建表后,我们模拟忘记添加条件和错误删除数据。选择*intokery_TESTFROMSYS。物体;DELETEFROMKERRY_TEST然后我们使用ApexSQLLog来挖掘事务日志。您将看到有许多相应的Delete记录,相应的RedoScript与原始SQL不同。

最近遇到一个误更新数据的问题,使用ApexSQL Log做挖掘事务日志的时候,发现ApexSQL Log生成的Redo Script跟原始SQL是有区别的。它们并不是完全一致的。只是逻辑上等价而已。如下所示,我们做一个测试,如下所示,创建一个表后,并模拟忘记添加条件,出现误删除数据的情况

 

SELECT * INTO KERRY_TEST FROM SYS.OBJECTS;
 
 
DELETE FROM KERRY_TEST

 

 

然后我们用ApexSQL Log挖掘事务日志,你会看到有很多对应的Delete记录,而且对应的Redo Script跟原始SQL是不一样的。如下所示,

 

 

image

 

 

下面是其中两个Redo  Script(为了方便查看,对脚本进行了格式化)

 

 

--DELETE (0003F73C:000065FC:000D) done at 2019-06-13 10:35:56.876 by xxxxxxx in transaction 0000:0ADF73EA (Committed)
BEGIN TRANSACTION;
DELETE  FROM [dbo].[KERRY_TEST]
WHERE   /*** WARNING: WHERE CLAUSE FOR THIS STATEMENT WAS GENERATED FOR A TABLE WITH NO PRIMARY KEY AND NO CLUSTERED INDEX ***/
        [name] = N'sysfgfrag' COLLATE Chinese_PRC_CI_AS
        AND [object_id] = 19
        AND [principal_id] IS NULL
        AND [schema_id] = 4
        AND [parent_object_id] = 0
        AND [type] = N'S ' COLLATE Latin1_General_CI_AS_KS_WS
        AND [type_desc] = N'SYSTEM_TABLE' COLLATE Latin1_General_CI_AS_KS_WS
        AND [create_date] = '20160101 10:46:55.060'
        AND [modify_date] = '20160101 10:46:55.100'
        AND [is_ms_shipped] = 1
        AND [is_published] = 0
        AND [is_schema_published] = 0;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;
 
 
 
--DELETE (0003F73C:000065FC:000A) done at 2019-06-13 10:35:56.876 by xxxxxx in transaction 0000:0ADF73EA (Committed)
BEGIN TRANSACTION;
DELETE  FROM [dbo].[KERRY_TEST]
WHERE   /*** WARNING: WHERE CLAUSE FOR THIS STATEMENT WAS GENERATED FOR A TABLE WITH NO PRIMARY KEY AND NO CLUSTERED INDEX ***/
        [name] = N'sysseobjvalues' COLLATE Chinese_PRC_CI_AS
        AND [object_id] = 9
        AND [principal_id] IS NULL
        AND [schema_id] = 4
        AND [parent_object_id] = 0
        AND [type] = N'S ' COLLATE Latin1_General_CI_AS_KS_WS
        AND [type_desc] = N'SYSTEM_TABLE' COLLATE Latin1_General_CI_AS_KS_WS
        AND [create_date] = '20160101 10:47:02.050'
        AND [modify_date] = '20160101 10:47:02.057'
        AND [is_ms_shipped] = 1
        AND [is_published] = 0
        AND [is_schema_published] = 0;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;
 

 

 

如果有聚集索引,你会看到没有WHERE条件的UPDATE、DELETE操作都会生成很多个对应的Redo Script,对应的WHERE条件则是聚集索引字段。如下测试所示:

SELECT  *
INTO    KERRY_TEST2
FROM    sys.objects;
 
CREATE CLUSTERED INDEX PK_KERRY_TEST2 ON KERRY_TEST2(OBJECT_ID);
 
UPDATE  KERRY_TEST2
SET     NAME = 'KERRY';
 
 
DELETE  FROM KERRY_TEST2;

 

 

image

 

下面是对应的UPDATE、DELETE操作的redo script

--UPDATE (0003F73C:0000700A:001F) done at 2019-06-13 11:27:26.036 by xxxxxx in transaction 0000:0ADF7404 (Committed)
BEGIN TRANSACTION; 
UPDATE  [dbo].[KERRY_TEST2]
SET     [name] = N'KERRY' COLLATE Chinese_PRC_CI_AS
WHERE   [object_id] = 3;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;
 
 
 
--    DELETE (0003F73C:00007482:00D9) done at 2019-06-13 11:27:35.406 by xxxxxx in transaction 0000:0ADF7405 (Committed)
BEGIN TRANSACTION;
DELETE  FROM [dbo].[KERRY_TEST2]
WHERE   [object_id] = 836302139;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;

 

这里只是简单记录一下这个事情,千万不要以为Redo Script跟原始SQL是完全一致的。如果遇到这种问题,如何判断呢?可以查看Transaction ID,以及对应的Begin Time , End Time,如下所示,你会发现它们是一致的

 

 

clip_image001[4]

免责声明:文章转载自《ApexSQL Log中的Redo Script跟原始SQL不一致问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Springboot整合AOPDelphi下EasyGrid使用体会下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

cetos7 systemd 详解

  CentOS7/RHEL7 systemd详解 目录1. 为什么是systemd(1) 关于Linux服务管理(2) SysV init的优缺点(3) UpStart的改进(4) systemd的诞生(5)为什么systemd能做到启动很快2. SysV init介绍(1) 什么是SystemV(2)SysV init的运行级别(3)SysV in...

WildCard的使用

一、关于WildCard:一个web应用,有成千上万个action声明,可以利用struts2提供的映射机制把多个彼此相似的映射关系简化成一个映射关系,即通配符。 1.新建类 ActionWildCard,验证通配符的方法 2.1添加Student需要实践的两个方法 add,deete package cn.cqvie.wildcard; import...

SQL---触发器

一、什么是触发器? 一段SQL代码,挂到某个表的某个增、删、改的操作上。 当这个表执行相应的操作时,就会触发这段相应的SQL代码。 触发器与存储过程的区别: 1.存储过程是独立于表存在的,触发器需要依附某个表的某个操作。 2.存储过程需要使用名称去调用才能执行,触发器则在表的操作过程中自动被触发调用。 二、触发器的分类: after触发器 ——先执行表的增...

术语“go”不被识别为cmdlet,函数,脚本文件或可操作程序的名称

1、执行:    $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine")    术语“go”不被识别为cmdlet,函数,脚本文件或可操作程序的名称 原文链接:https://www.ojit.com/article/205133...

Oracle中的Truncate和Delete语句

Oracle中的Truncate和Delete语句   首先讲一下,truncate命令:   语法:TRUNCATE  TABLE  table; 表格里的数据被清空,存储空间被释放。 运行后会自动提交,包括之前其它未提交的会话,因而一旦清空无法回退。 只有表格的创建者或者其他拥有删除任意表格权限的用户(如DBA)才能清空表格。 TRUNCATE  T...

OPENQUERY (Transact-SQL),跨数据库操作。

在指定的链接服务器上执行指定的传递查询。 该服务器是 OLE DB 数据源。 OPENQUERY 可以在查询的 FROM 子句中引用,就好象它是一个表名。OPENQUERY 也可以作为 INSERT、UPDATE 或 DELETE 语句的目标表进行引用。 但这要取决于 OLE DB 访问接口的功能。 尽管查询可能返回多个结果集,但是 OPENQUERY 只...