Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 比较两个具有相同架构的表的数据差异_Sql Server_Oracle_Compare_Schema - Fatal编程技术网

Sql server 比较两个具有相同架构的表的数据差异

Sql server 比较两个具有相同架构的表的数据差异,sql-server,oracle,compare,schema,Sql Server,Oracle,Compare,Schema,我正在处理一个典型的问题,需要比较两个模式完全相同的表的数据差异。 假设数据库为MS SQL或ORACLE 更确切地说,这是我试图实现的目标: 我有一个带有一些数据的表格 我正在创建表ORG的副本作为备份 现在我想更新ORG表中某些特定行中的某些特定列 找出备份表和组织表之间区别的最简单、最有效的方法是什么 我看不到像使用联合、枢轴、取消PIVOT等这样的选项。。但我感到困惑,需要一些关于最佳方式的指导 谢谢,试试这个 -- compare tables data and data2 with

我正在处理一个典型的问题,需要比较两个模式完全相同的表的数据差异。 假设数据库为MS SQL或ORACLE

更确切地说,这是我试图实现的目标:

  • 我有一个带有一些数据的表格
  • 我正在创建表ORG的副本作为备份
  • 现在我想更新ORG表中某些特定行中的某些特定列
  • 找出备份表和组织表之间区别的最简单、最有效的方法是什么

    我看不到像使用联合、枢轴、取消PIVOT等这样的选项。。但我感到困惑,需要一些关于最佳方式的指导

    谢谢,

    试试这个

    -- compare tables data and data2
    with data as
     (select 1 as id, 'A' as val
        from dual
      union
      select 2, 'B' from dual),
    data2 as
     (select 1 as id, 'A' as val
        from dual
      union
      select 2, 'BC' from dual)
    
     -- data not in data2 and data2 not in data:
     (select *
        from data2
      minus
      select * from data) union all
     (select *
        from data
      minus
      select * from data2);
    

    您可以使用集合运算符
    减号/相交
    ,具体取决于所需内容、两个表中行之间的差异或匹配

    要获得差值,请使用减号

    SELECT <here_goes_your_column_list> FROM org
    MINUS
    SELECT <here_goes_your_column_list> FROM backup
    
    SELECT <here_goes_your_column_list> FROM org
    INTERSECT
    SELECT <here_goes_your_column_list> FROM backup
    
    从组织中选择
    减
    从备份中选择
    
    要获得匹配,请使用相交:

    SELECT <here_goes_your_column_list> FROM org
    MINUS
    SELECT <here_goes_your_column_list> FROM backup
    
    SELECT <here_goes_your_column_list> FROM org
    INTERSECT
    SELECT <here_goes_your_column_list> FROM backup
    
    从组织中选择
    横断
    从备份中选择
    

    如果问题是检查两个表的标识,请参见。

    ,即答案是
    -表中包含 相同的数据或否-存在差异,存在另一种方法,在关系数据库中不太常见, 但最先进的文件

    这与检查下载文件的“正确性”(即与原始文件的标识)的方法相同 使用哈希代码。如果您看到相同的哈希代码,答案是
    yes
    您拥有正确的文件

    如何将这种方法转换为关系数据库

    Oracle提供了为字符串计算
    MD5
    哈希代码的函数

     select standard_hash('foo bar', 'MD5') hash_code from dual; 
    
     HASH_CODE                      
     --------------------------------
     327B6F07435811239BC47E1544353273 
    
    因此,您可以比较列值。 函数
    standard_hash
    也与
    CLOB
    s一起工作,因此(理论上)您可以连接 并计算整个表的哈希代码。但这不是正确的方法,记得吗 文件的哈希代码是通过组合行的哈希代码以增量方式计算的

    下面演示如何使用Java类
    Java.security.MessageDigest
    我使用的是Groovy脚本,不幸的是,这在PL/SQL中是不可能的

     MessageDigest digest = MessageDigest.getInstance("MD5") 
     byte[] md5hash 
    
     groovyCon.eachRow ('select txt from MY_TABLE order by id') 
        {
           digest.update(it.txt.getBytes(StandardCharsets.UTF_8))
        }   
    
     md5hash = digest.digest();
     println md5hash.encodeHex().toString()
    
    脚本启动散列代码,然后遍历行并更新散列代码,最后 将其预设为字符串。这是处理文件时的典型方法,其中行的顺序很重要。在关系表中 订单未定义。您认为与(a,b,c)和(c,b,a)表相同。

    请参阅如何使用
    XOR
    将散列码以顺序无关的方式组合的讨论

    下面是两个字符串的哈希代码组合的示例

     select UTL_RAW.BIT_XOR(standard_hash('foo', 'MD5'), standard_hash('bar', 'MD5')) hash_code from dual;
    
     HASH_CODE                      
     --------------------------------
     9B0805C206B7EBB8B6B9931D83E9F52A 
    
    这种方法有一个很大的优点,就是可以使用PL/SQL实现。看这里的例子 PL/SQL计算的一个实现,为整个表提供了一个MD5哈希代码

     select   MD5_XOR(txt) hash_code, count(*) cnt 
     from MY_TABLE;
    
     HASH_CODE                          CNT
     --------------------------------   -------
     173F1F8F85F1A154044B7629A23E949C   102 
    
    当然,您可以连接参数来计算整个表的哈希代码

     select MD5_XOR(to_char(id)||COL_TXT|| to_char(COL_DATE,'dd.mm.yyyy hh24:mi:ss')) md5  from  MY_TABLE;
    
    或者,您可以使用
    分组方式
    查看表格的各个部分,看看哪些组相同,哪些不同

    更好的是,如果这个聚合函数是由Oracle本机实现的,那么性能将会非常出色,而且会更好 使用基于集合的SQL比较操作(需要对表进行排序)。
    XOR
    联合收割机不需要 排序和排序具有
    O(N)
    复杂性,但用户实现受到上下文切换的影响


    请参阅将其作为Oracle本机实现的想法

    您是否正在尝试生成差异报告?或者从源表更新目标表?您实际使用的是这两个数据库中的哪一个?SQL可能会有所不同。
    update
    将完全不同。如果表具有主键或唯一键约束,则会有所帮助。您好,表没有任何主键。我尝试使用JOIN,它似乎涵盖了我感兴趣的大多数场景。。这就是我在p.city=q.cityi上从ORG x internal JOIN BACKUP q中选择count(*)时所做的。如果表没有任何主键,那么您也应该注意重复的行。使用
    internal JOIN
    进行的选择仅按列
    city
    进行比较。其他栏目的差异如何?如果更新了多个专栏,您将如何加入?谢谢。我试着加入,但似乎奏效了。我将探索您提供的选项,以备进一步完善。@Krishna没问题。如果答案有帮助,请将其标记为已回答,这也会帮助其他人!我在MSSQL上尝试过这个解决方案,得到Oracle上的负号与MSSQL上的负号相同。我需要具有不同数据的列,与上面提到的相同。这可以在MSSQL上实现吗?谢谢。我试着加入,但似乎奏效了。我将探讨您提供的选项,以备进一步改进。