获取任何 SQL 查询的 SHA-512

Get the SHA-512 of any SQL query

比较两个文本文件的常见做法是使用 SHA-512 [或任何其他实际的 SHA 算法]。如果两个 SHA 结果不相同,则文件不完全相同。

我想对两个 SQL 查询执行相同的操作。我只想知道查询是否使用 SHA-512 [或 sha-256 也可以] 给出 100% 相同的结果?

这可以实现吗?我正在使用 SQL 服务器...

只是为了帮助...

据了解,这两个查询 return 相同顺序的相同列。

你必须做到:

SELECT COUNT(*) FROM (
  ([YOUR_QUERY_A]
   EXCEPT
   [YOUR_QUERY_B]) -- A_B
  UNION ALL
  ([YOUR_QUERY_B]
   EXCEPT
   [YOUR_QUERY_A]) -- B_A
  ) EX

如果returns 0,则两个查询return相同

出于测试目的:

SELECT COUNT(*) FROM (
  (select 1 a
   EXCEPT
   select 1)
  UNION ALL
  (select 1
   EXCEPT
   select 1)
  ) EX

更改一些内部查询,看看有什么变化

下面是一些使用 2 种方法的示例 SQL。

  1. 为 XML & HASHBYTES
  2. EXCEPT
IF OBJECT_ID('tempdb..#tmpTest') IS NOT NULL DROP TABLE #tmpTest;
CREATE TABLE #tmpTest (
    id int identity(1,1) primary key, 
    col1 decimal(10,2), 
    col2 varchar(30)
);

insert into #tmpTest (col1, col2) values 
(1,'val1'),
(null,'val2'),
(3,null),
(4,'val4')
-- ,(5,'monkeywrench')
;

declare @SQL1 VARCHAR(1000);
declare @SQL2 VARCHAR(1000);
declare @SQLHASH VARCHAR(3000);
declare @SQLEXCEPT VARCHAR(5000);

set @SQL1 = 'select col1, col2 
from #tmpTest
where (col1 is null or col1 between 1 and 4)
';

set @SQL2 = 'select col1, col2 
from #tmpTest
where (col2 is null or col2 is not null)
';

set @SQLHASH = 'select 
IIF(LEN(query1.x) = LEN(query2.x) AND HASHBYTES(''SHA2_512'', query1.x) = HASHBYTES(''SHA2_512'', query2.x),''true'',''false'') as SameHash
from (
    '+ @SQL1 +'
    order by 1, 2
    for xml auto
) query1(x)
cross join (
    '+ @SQL2 +'
    order by 1, 2
    for xml auto
) query2(x)';

--select @SQLHASH as SQLHASH;
execute(@SQLHASH);

set @SQLEXCEPT = 'select 
IIF(count(*) = 0,''true'',''false'') as SameRecords
from (
    select * from
    (
        '+ @SQL1 +'
        except
        '+ @SQL2 +'
    ) as q1exceptq2

    union all

    select * from (
        '+ @SQL2 +'
        except
        '+ @SQL1 +'
    ) as q2exceptq1
) q';

--select @SQLEXCEPT as SQLEXCEPT;
execute(@SQLEXCEPT);

在此示例中,两个动态查询 return 'true'.

但请注意,仅仅因为结果集相同,并不意味着使用的标准是等价的。
他们目前 return 得到相同的结果可能只是运气不好。
(只需取消对 monkeywrench 记录的注释即可从两者中获取 false)

另外,关于 FOR XML。当其中一个 ORDER BY 不同时,那么得到的 XML 和 HASH 也会不同。

使用 EXCEPT 时,您只能在末尾添加 ORDER BY,因为它会对组合结果集进行排序。