Получите SHA-512 любого SQL-запроса - PullRequest
0 голосов
/ 06 июня 2018

Обычной практикой для сравнения двух текстовых файлов является использование SHA-512 [или любого другого реализованного алгоритма SHA].Если два результата SHA не совпадают, то файлы не совсем совпадают.

Я хотел бы сделать то же самое с двумя запросами SQL.Я просто хочу знать, дает ли запрос 100% идентичный результат или нет с SHA-512 [или sha-256 тоже будет в порядке]?

Возможно ли это сделать?Я использую SQL Server ...

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Вот пример SQL, который использует 2 метода.

  1. ДЛЯ XML & ХАШБИТЫ
  2. ИСКЛЮЧИТЬ
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);

В этом примере оба динамических запроса возвращают значение «true».

Но учтите, что тот факт, что наборы результатов совпадают, не означает, что используемые критерии эквивалентны.
Это может быть просто плохоповезло, что они в настоящее время возвращают одинаковые результаты.
(просто раскомментируйте запись с ключом-ключом, чтобы получить ложное от обоих)

Кроме того, о FOR XML.Если один из ORDER BY отличается, то результирующий XML и HASH также будут отличаться.

Хотя с ИСКЛЮЧЕНИЕМ вы можете добавить только ORDER BY в конце, потому что он сортирует объединенный набор результатов.

0 голосов
/ 06 июня 2018

Просто чтобы помочь ...

Понятно, что оба запроса возвращают одинаковые столбцы в одном и том же порядке.

Вы должны сделать:

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

Если возвращается0, оба запроса возвращают одно и то же

Для целей тестирования:

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

Измените некоторый внутренний запрос и посмотрите, что изменится

...