Создать хэш для набора строк в SQL Server
Есть ли способ в 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% медленнее, когда приходится обрабатывать дублирующиеся данные.
Большое спасибо
4 ответа
Вы можете использовать агрегат CHECKSUM_AGG. это сделано для этой цели.
select HashBytes('md5',convert(varbinary(max),(SELECT * FROM MyChildTable WHERE ParentId = 2 FOR XML AUTO)))
но HashBytes ограничен только 8000 байтов... вы можете сделать функцию, чтобы получить де Md5 для каждых 8000 байтов....
Для однорядных хэшей:
select HASHBYTES('md5', Name + Description + AnotherColumn)
FROM MyChildTable WHERE ParentId = 2
для контрольной суммы таблицы:
select sum(checksum(Name + Description + AnotherColumn)*1.0)
FROM MyChildTable WHERE ParentId = 2
Другой подход:
-- 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;