问题
A common practice to compare two text file is to use the SHA-512 [or any other realted SHA algo]. If two SHA results are not the same then the files are not exactely the same.
I would like to do the same with two SQL queries. I just want to know if the queries gives 100% identical result or not with a SHA-512 [or sha-256 would be OK as well]?
Is that possible to perform that? I am using SQL Server...
回答1:
Just to help...
It's understood that both queries return the same columns in the same order.
You must do:
SELECT COUNT(*) FROM (
([YOUR_QUERY_A]
EXCEPT
[YOUR_QUERY_B]) -- A_B
UNION ALL
([YOUR_QUERY_B]
EXCEPT
[YOUR_QUERY_A]) -- B_A
) EX
If returns 0, both queries return the same
For test purposes:
SELECT COUNT(*) FROM (
(select 1 a
EXCEPT
select 1)
UNION ALL
(select 1
EXCEPT
select 1)
) EX
Change some inner query and look what changes
回答2:
Here's some example SQL that uses 2 methods.
- FOR XML & HASHBYTES
- 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);
In this example, both dynamic queries return 'true'.
But do note that just because the result sets are the same, doesn't mean that the criteria used are equivalent.
It might just be bad luck that they are currently returning the same results.
(just uncomment the monkeywrench record to get false from both)
Also, about the FOR XML. When one of the ORDER BY is different, then the resulting XML and HASH will also be different.
While with an EXCEPT you can only add an ORDER BY at the end, because it sorts the combined resultset.
来源:https://stackoverflow.com/questions/50724104/get-the-sha-512-of-any-sql-query