Подтвердить что ты не робот

Создание хэша для набора строк в sql-сервере

Есть ли способ в SQL Server 2012 генерировать хэш из набора строк и столбцов?

Я хочу создать хеш, сохранить его в родительской записи. Когда произойдет обновление, я сравню входящий хеш с хешем родительской записи, и я узнаю, изменились ли данные.

Итак, что-то вроде этого было бы хорошо:

SELECT GENERATEHASH(CONCATENATE(Name, Description, AnotherColumn))
FROM MyChildTable WHERE ParentId = 2 -- subset of data belong to parent record 2

"CONCATENATE" будет представлять собой агрегатную функцию, которая не только конкатенирует столбцы, но также и строки внутри набора результатов. Как и MAX, но возвращающий все как конкатенацию строк.

Надеюсь, это поможет вам понять, что я имею в виду в любом случае!

Основная проблема, которую я пытаюсь решить, заключается в том, что моя клиентская система выполняет импорт огромного количества иерархических данных. Если я смогу избежать обработки с помощью хешей, то я думаю, что это сэкономит много времени. На данный момент SP работает на 300% медленнее при обработке повторяющихся данных.

Большое спасибо

4b9b3361

Ответ 1

Вы можете использовать агрегат CHECKSUM_AGG. это сделано для этой цели.

Ответ 2

select HashBytes('md5',convert(varbinary(max),(SELECT * FROM MyChildTable WHERE ParentId = 2 FOR XML AUTO)))

но HashBytes ограничено только 8000 байтами... вы можете сделать функцию для получения Md5 для каждых 8000 байтов....

Ответ 3

Для однострочных хэшей:

select HASHBYTES('md5', Name + Description + AnotherColumn)
FROM MyChildTable WHERE ParentId = 2

для контрольной суммы таблицы:

select sum(checksum(Name + Description + AnotherColumn)*1.0)
FROM MyChildTable WHERE ParentId = 2

Ответ 4

Другой подход:

-- compute a single hash value for all rows of a table
begin

    set nocount on;

    -- init hash variable
    declare @tblhash varchar(40);
    set @tblhash = 'start';

    -- compute a single hash value
    select @tblhash = sys.fn_varbintohexsubstring(0, hashbytes('sha1',(convert(varbinary(max),@tblhash+
    (select sys.fn_varbintohexsubstring(0,hashbytes('sha1',(convert(varbinary(max),
    -- replace 'select *' if you want only specific columns to be included in the hash calculation
    -- [target table] is the name of the table to calc the hash from
    -- [row_id] is the primary key column within the target table
    -- modify those in the next lines to suit your needs:
    (select * from [target_table] obj2 where obj2.[row_id]=obj1.[row_id] for xml raw)
    ))),1,0))
    ))),1,0)
    from [target_table] obj1;

    set nocount off;

    -- return result
    select @tblhash as hashvalue;

end;