我有一个 SQL Server 数据库,其中有一个表,其中包含 varbinary(256) 类型的字段。
当我通过彩信中的查询查看此二进制字段时,该值如下所示:
0x004BC878B0CB9A4F86D0F52C9DEB689401000000D4D68D98C8975425264979CFB92D146582C38D74597B495F87FEA09B68A8440A
当我使用 CFDUMP 查看同一字段(和同一记录)时,该值如下所示:
075-56120-80-53-10279-122-48-1144-99-21104-1081000-44-42-115-104-56-10584373873121-49-714520101-126-61-115116891237395-121-2-96-101104-886810
(对于下面的示例,原始二进制值为@A
,上面的CFDUMP值为@B
)
我尝试使用 CAST(@B as varbinary(256))
但没有获得与 @A
相同的值。
我必须做什么才能将从 CFDUMP 检索到的值转换为正确的二进制表示形式?
注意:我的数据库中不再有适用的记录。我需要将 @B
转换为可以重新插入 varbinary(256) 字段的正确值。
最佳答案
(根据评论扩展)
我的意思并不是讽刺,但是它们如何显示二进制文件有什么区别?这只是数据呈现方式的差异。这并不意味着实际的二进制值不同。
这与日期的处理方式类似。在内部,他们是一个很大的数字。但由于大多数人不知道 1234567890
代表哪个日期,因此应用程序选择以更人性化的格式显示该数字。因此 SSMS 可能将日期显示为 2009-02-13 23:31:30.000
,而 CF 可能将其显示为 {ts '2009-02-13 23:31:30'}
。尽管演示不同,但其内部值(value)仍然相同。
就二进制而言,SSMS 将其显示为十六进制。如果您在查询列上使用 binaryEncode()
并将二进制转换为十六进制,您可以看到它是相同的值。只是没有前导 0x
:
writeDump( binaryEncode(yourQuery.binaryColumn, "hex") )
如果您在二进制方面遇到其他问题,能否详细说明一下?
更新:
不幸的是,我认为您无法轻松地将 cfdump 表示形式转换回二进制。与 Railo 的实现不同,Adobe 的 cfdump
只是将各个字节的数字表示形式连接成一个大字符串,没有分隔符。 (破折号只是负数)。您可以通过循环示例字符串的字节来重现这一点。下面的代码生成与您发布的相同的数字字符串。
bytes = binaryDecode("004BC878B0CB9A4F...", "hex");
for (i=1; i<=arrayLen(bytes); i++) {
WriteOutput( bytes[i] );
}
我认为理论上可以将该字符串转换为二进制,但这会非常困难。 AFAIK,没有办法准确确定一个数字(或字节)的开始位置和另一个数字的结束位置。有一些线索,但最终只能归结为猜测。
Railo 的实现显示由破折号“-”分隔的字节值。两个连续的破折号表示负数。即“0”,“75”,“-56”,...
0-75--56-120--80--53--102-79--122--48--11-44--99--21-104--108-1-0-0-0--44--42--115--104--56--105-84-37-38-73-121--49--71-45-20-101--126--61--115-116-89-123-73-95--121--2--96--101-104--88-68-10
因此您可能可以将该字符串解析回字节数组。然后使用 <cfqueryparam cfsqltype="CF_SQL_BINARY" ..>
将二进制文件插入数据库。不幸的是,这对您没有帮助,但解释可能会对下一个人有所帮助。
此时,我认为最好的选择是从数据库备份中恢复数据。
关于sql-server - 使用 CFDUMP 查看时的二进制数据不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26952492/