哈希一行SQL行?

mez*_*hic 23 sql sql-server sql-server-2008

有没有办法在SQL表中使用md5sum来检查是否有任何列已被修改?

我想检查是否有任何特定列已被更改,而不是我在文本文件中保存的数据的旧副本(我将在C#中使用md5sum).

编辑:每行md5suming

Rem*_*anu 20

CHECKSUM(*),BINARY_CHECKSUM(*)CHECKSUM_AGG.他们做CRC32就像checkum一样,但是为了检测行的变化,它应该绰绰有余(你说的是假冒负面碰撞中有40亿的机会).

使用加密哈希HASHBYTES要求您构造表示"行"的表达式.

  • 根据环境的不同,仍有40亿分之一的频率足以预期它最终可能会发生.此外,在某些环境中,此类事件可能是灾难性的.我不知道OP的需求,但是MS甚至不推荐*不*使用`CHECKSUM()`来确定行的变化? (4认同)
  • @Dems:但我同意在很多情况下,40亿分之一的概率太高.请记住,既然你将已知行与另一个已知行进行比较,那么就没有[中间相遇](http://en.wikipedia.org/wiki/Meet-in -the-middle_attack)问题.如果错误否定导致世界末端灾难,那么*only*解决方案是进行完整的逐字节比较,*所有*哈希都是易于定义的冲突. (4认同)
  • 两个注意事项:HASHBYTES 限制为 8000 字节的输入,并且 CHECKSUM() 为正小数和负小数生成相同的值 - 即,如果 x 是 int CHECKSUM([other columns], x) 和 CHECKSUM([other columns], - x) 会不同,但如果 x 是小数,它们将相同。 (3认同)
  • @Dems:不知道 OP 需要我不能说 CHECKSUM 是否足够好。我不会仅仅因为 `*` 的便利性很难与做 `HASHBYTES` 相提并论而驳回它。提出一个表示行以进行散列的表达式并非易事,当您考虑架构更改时更是如此。 (2认同)
  • 这些功能不如MSDN中那么好.如果输入相似,很容易得到CHECKSUM碰撞.看看这里:[link](http://stackoverflow.com/questions/12841331/tsql-checksum-conundrum)另外,如果你使用CHECKSUM_AGG要小心 - 它在引擎盖下使用XOR,所以它很容易也会发生碰撞.你可以在这里阅读:[link](http://michaeljswart.com/2009/02/checksum_agg-a-very-nifty-function/)我不相信那些功能 (2认同)

Muf*_*lix 11

如果您有SQL Server 2008或更新版本,您可以使用:

SELECT HASHBYTES('SHA1', (SELECT TOP 1 * FROM dbo.Table FOR XML RAW))
Run Code Online (Sandbox Code Playgroud)

要么

SELECT  
    HASHBYTES('SHA1',(
        SELECT  * 
        FROM    dbo.myTable as  tableToHash 
        where   tableToHash.myUniqueKey=myTable.myUniqueKey 
        FOR XML RAW
    ))                                              as  rowSHA1
from    dbo.myTable;
Run Code Online (Sandbox Code Playgroud)

  • @FlorianCastelain 因为您需要以某种方式将列放入一个文本行中,所以您还可以使用`SELECT cast(column1 as nvarchar(max)) + cast(column2 as nvarchar(max)) + ... FROM dbo.myTable as tableToHash`反而 (2认同)

Bru*_*tas 8

我必须开发一个解决方案来比较表结构并运行一个过程来导入表之间的差异。

我使用下面的代码来选择数据

--> 表结构

create table #table1 (
campo varchar(10)
,campo1 varchar(10)
)

create table #table2 (
campo varchar(10)
,campo1 varchar(10)
)
Run Code Online (Sandbox Code Playgroud)

--> 插入值

insert into #table1 values ('bruno',1)
insert into #table1 values ('bruno',2)
insert into #table2 values ('bruno',1)
insert into #table2 values ('bruna',2)
Run Code Online (Sandbox Code Playgroud)

--> 创建一个哈希列进行比较

select *,HASHBYTES('SHA1', (select z.* FOR XML RAW)) as hash
    into #compare1
 from #table1 z 

select *,HASHBYTES('SHA1', (select k.* FOR XML RAW)) as hash
    into #compare2
 from #table2 k 
Run Code Online (Sandbox Code Playgroud)

--> 检查有什么不同的行

select * from  #compare1 a
full outer join #compare2 b on a.hash = b.hash
where ( a.hash is null or b.hash is null )
Run Code Online (Sandbox Code Playgroud)

也许这对于需要同样东西的人很有用在这里查找上面解释的代码