最近想做一些数据修补,尝试更新一个varbinary(MAX)类型的列,更新值是这样的:
0xFFD8F...6DC0676
但是,更新查询成功运行后,该值变为:
0x0FFD8...6DC067
最后 4 位似乎丢失了,或者整个值右移了一个字节...
我尝试删除整行并运行插入查询,同样的事情发生了!
谁能告诉我为什么会发生这种情况以及如何解决它?谢谢!
我尝试了几种不同长度的二进制文件,以获得最大的 43658 个字符(每个字符代表 4 位,总计约 21 KB),更新查询正常运行。多1个字符就会出现上面的“bug”...
PS1:对于较短长度的 varbinary 作为更新值,一切都可以
PS2:如果有帮助的话,我可以发布整个二进制字符串,但它真的很长,我不确定是否适合发布在这里
编辑: 感谢您的帮助!
正如有人建议的,插入的值可能是奇数个4位,所以在它前面有一个0附加。这是我关于该值的更新信息:
该值的长度为43677个字符,不包括“0x”,这意味着是的,它是奇怪的
它确实解释了为什么前面插入了“0”,但没有解释为什么最后一个字符消失...
然后我做了一个实验:
我插入一个偶数长度值,并在原始值之前手动添加“0”,
现在要更新的值为
0x0FFD8F...6DC0676
长度为 43678 个字符,不包括“0x”
结果没有运气,更新后的值依然
0x0FFD8...6DC067
最佳答案
您用于更新的二进制常量0xFFD8F...6DC0676
似乎包含奇数个十六进制数字。 SqlServer 在模式的开头添加了半字节,以便它代表整数字节。
运行以下简单查询可以看到相同的效果:
select 0x1, 0x104
这将返回 0x01
和 0x0104
。
截断可能是由于 SSMS 中的一些限制造成的,可以在以下实验中观察到:
declare @b varbinary(max)
set @b = 0x123456789ABCDEF0
set @b = convert(varbinary(max), replicate(@b, 65536/datalength(@b)))
select datalength(@b) DataLength, @b Data
返回的结果是 65536
和 0x123456789ABCDEF0...EF0123456789ABCD
,但是如果在 SSMS 中我复制数据列,我将得到 43677 个字符长度的模式(这是没有的)前导 0x),有效长度为 21838.5 字节。因此,您似乎不应该(如果您这样做)依赖于通过 SSMS 中的复制/粘贴获得的长二进制数据值。
可靠的替代方案可以使用中间变量:
declare @data varbinary(max)
select @data = DataXXX from Table_XXX where ID = XXX
update Table_YYY set DataYYY = @data where ID = YYY
关于sql - 更新 SQL Server 2012 中的 varbinary(MAX) 字段丢失最后 4 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29913283/