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

标签 sql t-sql sql-server-2012 varbinary

最近想做一些数据修补,尝试更新一个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

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

关于sql - 更新 SQL Server 2012 中的 varbinary(MAX) 字段丢失最后 4 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29913283/

相关文章:

mysql - SQL - 多个多对多关系过滤 SELECT

sql - 在一个语句中从序列中查询多个 NEXTVAL

sql - 使用sql在现有整数子集中不存在的范围内查找下一个可用整数

sqlite alter table 在单个语句中添加多个列

sql - 在 SQL Server 存储过程中使用带有通配符的单词列表

sql-server - 为什么搜索 n 个空格字符的字符串会返回不一致的结果?

sql-server - 在大尺寸表上创建外键

sql - 查询以处理单个参数以及 "All"情况

sql - 在 T-SQL 中创建快捷函数

c# - 使用存储过程更新动态名称表