小编典典

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

sql

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

0xFFD8F … 6DC0676

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

0x 0 FFD8 … 6DC067

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

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

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

我尝试了几种不同长度的二进制文件,最大为 43658个 字符(每个字符代表4位,总计约21
KB),更新查询正常运行。再增加1个字符将使上述“错误”出现…

PS1 :对于较短长度的varbinary作为更新值,一切正常

PS2 :如果有帮助,我可以将整个二进制字符串发布出来,但是它确实很长,我不确定是否适合在这里发布

编辑: 感谢您的帮助!

就像有人建议的那样,插入的值可能是4位的奇数,因此在其前面有一个0附加值。这是我关于值的更新信息:

该值是 43677个 字符,长后缀 “ 0x”,这 是肯定的,很奇怪

它确实说明了为什么在前面插入了“ 0”,但 没有说明为什么最后一个字符消失了…

然后我做一个实验:

我插入一个 偶数长度值,并在原始值之前手动添加一个‘0’

现在要更新的值是

0x 0 FFD8F … 6DC067 6

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

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

0x0FFD8 … 6DC067


阅读 257

收藏
2021-04-14

共1个答案

小编典典

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

您可以通过运行以下简单查询看到相同的效果:

select 0x1, 0x104

这将返回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

返回的结果是655360x123456789ABCDEF0...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
2021-04-14