更新 SQL Server 2012 中的 varbinary(MAX) 字段丢失最后 4 位

Update varbinary(MAX) field in SQLServer 2012 Lost Last 4 bits

最近想做一些数据修补,尝试更新一个varbinary(MAX)类型的列,更新值是这样的:

0xFFD8F...6DC0676

但是更新查询运行成功后,值变为:

0x0FFD8...6DC067

似乎最后 4 位丢失了,或者整个值右移了一个字节...

我尝试删除整行并 运行 一个 插入查询 ,同样的事情发生了!

谁能告诉我为什么会这样,我该如何解决?谢谢!

我尝试了几种不同长度的二进制文件,最大 43658个字符(每个代表4位,共约21KB),更新查询正常运行s。再多1个字符就会出现上面的"bug"...

PS1: 对于更短长度的varbinary作为更新值,一切都ok

PS2:如果有帮助,我可以post整个二进制字符串,但它真的很长,我不确定它是否适合post这里

已编辑: 感谢您的帮助!

有人建议,插入的值可能是4位的奇数个,所以在它前面追加了一个0。这是我的价值更新信息:

值是 43677 个字符长,不包括“0x”,这意味着 是的,它是奇数

它确实解释了为什么前面插入了一个“0”,但是没有解释为什么最后一个字符消失了...

那我做个实验:

我插入了一个偶数长度值,我在原值前手动添加了一个'0',

现在要更新的值为

0x0FFD8F...6DC0676

长度为 43678 个字符,不包括“0x”

结果没有运气,更新后的值还是

0x0FFD8...6DC067

您用于更新的二进制常量 0xFFD8F...6DC0676 似乎包含奇数个十六进制数字。并且 SqlServer 在模式的开头添加了半字节,以便它代表完整的字节数。

可以看到同样的效果运行下面的简单查询:

select 0x1, 0x104

这将 return 0x010x0104

截断可能是由于 SSMS 中的一些限制,可以在以下实验中观察到:

declare @b varbinary(max)
set @b = 0x123456789ABCDEF0
set @b = convert(varbinary(max), replicate(@b, 65536/datalength(@b)))
select datalength(@b) DataLength, @b Data

结果 returned 是 655360x123456789ABCDEF0...EF0123456789ABCD,但是如果在 SSMS 中复制数据列,我将得到 43677 个字符长度的模式(这是没有前导 0x) ,实际上是 21838.5 字节。因此,您似乎不应该(如果这样做)依赖通过 SSMS 中的 copy/paste 获得的长二进制数据值。

可靠的替代方法可以使用中间变量:

declare @data varbinary(max)
select @data = DataXXX from Table_XXX where ID = XXX
update Table_YYY set DataYYY = @data where ID = YYY