SQLSERVER中如何快速比较两张表的不一样

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 原文:SQLSERVER中如何快速比较两张表的不一样SQLSERVER中如何快速比较两张表的不一样 不知不觉要写2014年的最后一篇博文了~   一般来说,如何检测两张表的内容是否一致,体现在复制的时候发布端和订阅端的两端的数据上面 我这里罗列了一些如何从数据库层面来解决此类问题的方法 ...
原文: SQLSERVER中如何快速比较两张表的不一样

SQLSERVER中如何快速比较两张表的不一样

不知不觉要写2014年的最后一篇博文了~

 

一般来说,如何检测两张表的内容是否一致,体现在复制的时候发布端和订阅端的两端的数据上面

我这里罗列了一些如何从数据库层面来解决此类问题的方法


第一步当然就是检查记录数是否一致,否则不用想其他方法了~
这里我们用两张表t1_old,t1_new来演示


方法介绍

 

方法一:老老实实看表结构和表记录数,弊端是根本看不到两张表的数据是否一致,只是看到表结构和记录数是否一致

--表结构:
 CREATE TABLE t1_old (
  id int NOT NULL,
  log_time DATETIME DEFAULT ''
) ;
CREATE TABLE t1_new ( id int NOT NULL, log_time DATETIME DEFAULT '' ) ; --两表的记录数都为100条。 select count(*) from t1_old; select count(*) from t1_new;

 

 

方法二:加法去重 union 运算符排除重复的,但是有bug,在某些情形下不能简单表示结果集一致,相当于无效

由于Union 本身具备把上下两条连接的记录做唯一性排序,所以这样检测起来比较简单

SELECT  COUNT(*)
FROM    ( SELECT    *
          FROM      [t1_old]
          UNION
          SELECT    *
          FROM      [t1_new]
        ) AS T;


INSERT INTO [dbo].[t1_new]
        ( [id],[log_time] )
VALUES(1,''),(3,''),(4,'')

INSERT INTO [dbo].[t1_old]
        ( [id],[log_time] )
VALUES(1,''),(2,''),(3,'')

SELECT * FROM [dbo].[t1_new]
SELECT * FROM [dbo].[t1_old]

SELECT  COUNT(*)
FROM    ( SELECT    *
          FROM      [t1_new]
          UNION
          SELECT    *
          FROM      [t1_old]
        ) AS T;

两表数据

查询出来的结果是4

 

 

方法三:EXCEPT  减法归零

SELECT  COUNT(*)
FROM    ( SELECT    *
          FROM      [dbo].[t1_new]
          EXCEPT
          SELECT    *
          FROM      [dbo].[t1_old]
        ) AS T;

SELECT  COUNT(*)
FROM    ( SELECT    *
          FROM      [dbo].[t1_old]
          EXCEPT
          SELECT    *
          FROM      [dbo].[t1_new]
        ) AS T;

SELECT * FROM [dbo].[t1_new]

SELECT * FROM [dbo].[t1_old]

这里检测出来结果不对,那么就直接给出不一致的结论

 

 

方法四:用全表INNER JOIN,这个也是最烂的做法,当然这里指的是在表记录数超级多的情况下

DECLARE @t1_newcount BIGINT
DECLARE @count BIGINT


SELECT  @t1_newcount = COUNT(*)
FROM    t1_new;


SELECT  @count = COUNT(*)
FROM    [t1_old] AS a
        INNER JOIN [t1_new] AS b ON [b].[id] = [a].[id]
                                    AND [b].[log_time] = [a].[log_time] --如果表中还有其他字段的自行添加
PRINT @count
PRINT @t1_newcount
IF ( @count = @t1_newcount )
    BEGIN 
        SELECT  'equal'
    END 
ELSE
    BEGIN
        SELECT  'not equal'

    END 

 

 

方法五:借助SQLSERVER自带的tablediff工具,当初微软制作这个工具的目的就是用于比较复制中发布表和订阅表的数据一致

identical是相等的意思

 

方法六:借助发布端的验证订阅功能,验证订阅端跟发布端的数据是否一致

 

 

方法七:用checksum校验,比较两张表里的内容的checksum值是否一致

但是这种方法也只局限于两表结构一摸一样

我把[t1_new]表的数据复制到一张新的表以便进行比较

SELECT * FROM [dbo].[t1_new]
SELECT * FROM [dbo].[t1_newreplica]



SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_old]
SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_new]
SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_newreplica]


总结

从上面几种数据库提供的方法来看,用EXCEPT减法来归零相对来说比较可靠,其他的方法比较适合在特定的情形下来检测

 

如有不对的地方,欢迎大家拍砖o(∩_∩)o 

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
11月前
|
SQL
重置SQLSERVER表的自增列,让自增列重新计数
重置SQLSERVER表的自增列,让自增列重新计数
154 0
|
19天前
|
SQL Java 网络安全
实时计算 Flink版操作报错合集之SQLserver表没有主键,同步的时候报错如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
30 1
|
22天前
|
数据库 数据库管理 Python
sqlserver练习----涉及多个表的连接查询
sqlserver练习----涉及多个表的连接查询
19 0
|
22天前
|
SQL 关系型数据库 数据库
Flink CDC产品常见问题之SQLserver cdc 开启 cdc表没有记录如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
7月前
|
数据库
Mac SQLServer删除数据库中所有的表
Mac SQLServer删除数据库中所有的表
31 0
|
11月前
|
SQL 存储 XML
数据库视频第四章(sql server 2008数据类型、对于表的管理、规则的创建与删除)
数据库视频第四章(sql server 2008数据类型、对于表的管理、规则的创建与删除)
77 0
|
11月前
|
SQL
sql server 获取自增列下一个值或者获取指定表的主键值
sql server 获取自增列下一个值或者获取指定表的主键值
|
数据库
SQLSERVER查询整个数据库中某个特定值所在的表和字段的方法
SQLSERVER查询整个数据库中某个特定值所在的表和字段的方法
361 0
|
SQL 存储 Oracle
sql server系列_01表和约束
sql server系列_01表和约束
sql server系列_01表和约束
|
SQL 数据库
tp读取sqlserver数据库一个表的时候一个字段类型是text,数据有空格读取出的数据有乱码解决方案...
$sql="SELECT *, REPLACE(CONVERT(varchar(500), GoodsInfo), CHAR(32), ' ') AS GoodsInfo FROM tDelivery WHERE (DeliveryID = '$DeliveryID')"; GoodsInfo这字段是text类型的,不支持REPLACE函数,所以先用CONVERT把这个字段强行转化成varchar500,然后再用REPLACE 把字段里面的空格 CHAR(32)替换成空就ok了!
292 0