如何解决mariadb/mysql:如何将 BLOB 的一部分转换/解包为整数或双精度等
我使用 mariaDB/mysql 数据库对二进制数据的结构进行“逆向工程”。 名为“数据”的列包含 152 字节长的二进制“blob”。
在另一列中,我列出了我期望的信息类型: 例如col2: "timestamp" (unix formatted),col3: "size1" uint32,col4: "length" 4 byte float,.... etc.
当我开始时,所有这些列都包含 NULL。
现在我写下一篇论文:“data”中 blob 的字节 8:12 是一个 4 字节的 int 并解码为“size1”等等。 为了评估我的论文,我想通过从“数据”中的 blob 中提取来填充 col3/“size1”。
所以我现在需要的是一个 SQL (mariadb) UPDATE,它从 blob 中提取字节并将其存储在“col3”中。 一列称为“pulse_max”。有了它,它工作得很好,因为我只需要 1 个字节:
更新字典2 SET pulse_max=ascii(SUBSTRING(data,147,1));
但是如何将 blob 的较大(2、4 字节等)部分“转换”/解压缩为 int、uint、double、unixtimestamp 等? 像这样的事情失败了:(“tracklenght”列是一个 4 字节的 uint。)
UPDATE dictionary2 SET tracklength= binary(SUBSTRING(data,113,4));
==> 警告:#1366 Falscher integer-Wert: '\x94L\xFEE' für Feld 'tracklength' in Zeile 1
UPDATE dictionary2 SET duration_time=CONV(REVERSE(HEX(substring(data,109,4))),16,10);
==> 这是废话(我的源数据是小端)。也许这 4 个字节的顺序有误?
我知道我可以用 C/perl/python/etc 做这一切。 (htonl,unpack 等) - 但是这些程序不允许我存储很多数据样本并允许对我的论文进行大量评估。
当然我可以使用 python/perl mariadb 连接器。但是我想直接在 SQL 中进行并将例程存储在数据库中。
解决方法
嗯,我有一些帖子。我把它们都删除了,因为现在我有了一个不错的解决方案。我期望 SQL/mariadb 有一个集成的“功能”。事实并非如此,所以我自己写了。如果您正在寻找类似的解决方案,那么您就在这里:
如果存在则删除函数 unpackf4;
分隔符 //
创建函数 unpackf4(b BLOB(4))
返回浮动确定性
开始
声明 f_value 浮动;
声明 binstr CHAR(32);
SET binstr = LPAD(CONV(HEX(CAST(reverse(b) AS CHAR(10000) CHARACTER SET)
utf8)),16,2),32,'0');
设置 f_value =
POW(-1,CONV(SUBSTRING(binstr,1,1),2,10))*
POW( 2,CONV(SUBSTRING( binstr,8),10)-127)*
(1+ CONV(SUBSTRING(binstr,10,23),10)/POW(2,23));
返回 f_value;
结尾; //
分隔符;
有了这个函数,你可以简单地将一个 blob 列“转换/解包”到 float32(double64 将类似):
UPDATE dictionary2 SET tracklength = unpackf4(substring(data,113,4));
虽然显然 DATA 是一个 blob 列,而 tracklenght 是一个浮点列。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。