我正在尝试在 Spiceworks 中编写使用 SQLite 查询的自定义报告。该报告将获取硬盘序列号,不幸的是,这些序列号以几种不同的方式存储,具体取决于机器上的 Windows 和 WMI 版本。
三个常见示例(足以解决实际问题)如下:
实际序列号: 5VG95AZF
带前导空格的 2020202057202d44585730354341543934383433
十六进制字符串:带前导零的十六进制字符串: 3030303030303030313131343330423137454342
这两个十六进制字符串更加复杂,因为即使将它们转换为 ASCII 表示,每对数字实际上都是倒数的。这是一个例子:
3030303030303030313131343330423137454342
评估为00000000111430B17ECB
但是,该硬盘驱动器上的实际序列号是1141031BE7BC
,没有前导零并且交换了字节。根据我在本网站上阅读的其他问题和答案,这与数据的“字节顺序”有关。
到目前为止,我的临时查询看起来像这样(缩短到仅相关部分):
SELECT pd.model as HDModel,
CASE
WHEN pd.serial like "30303030%" THEN
cast(('X''' || pd.serial || '''') as TEXT)
WHEN pd.serial like "202020%" THEN
LTRIM(X'2020202057202d44585730354341543934383433')
ELSE
pd.serial
END as HDSerial
该查询的结果是这样的:
HDModel HDSerial
----------------- -------------------------------------------
Normal Serial 5VG95AZF
202020% test case W -DXW05CAT94843
303030% test case X'3030303030303030313131343330423137454342'
这表明当给定一个完全文字数字(202020% 线)时,X'....'
符号样式确实转换为正确(但向后)的结果。W -DXW05CAT94843
但是,我需要找到一种方法来对列中的实际数据执行相同的操作,但pd.serial
我找不到方法。
我最初的想法是,如果我可以构建符号的字符串表示X'...'
,那么也许cast()
会评估它。但正如您所看到的,这最终只是吐出X'3030303030303030313131343330423137454342'
而不是预期的00000000111430B17ECB
. 这意味着串联工作正常,但我找不到与手动测试用例一样将其评估为十六进制的方法。
我整个早上都在谷歌搜索,看看是否缺少一些语法,但我最接近的是使用||
运算符的连接。
编辑: 最终我只想能够在我的查询中有一个简单的 case 语句,如下所示:
SELECT pd.model as HDModel,
CASE
WHEN pd.serial like "30303030%" THEN
LTRIM(X'pd.serial')
WHEN pd.serial like "202020%" THEN
LTRIM(X'pd.serial')
ELSE
pd.serial
END as HDSerial
但是因为 pd.serial 被单引号括起来,所以它被当作文字字符串而不是作为该列中包含的数据。我的希望是/是我需要指定一个字符或运算符,比如X'$pd.serial'
或其他东西。
结束编辑
如果我能克服这第一个障碍,我的下一个任务将是尝试删除前导零(LTRIM 吃前导空格的方式)并反转字节,但老实说,即使那部分不是,我也会满足。这是不可能的,因为在 Excel 中对该报告进行后处理并不难。
如果有人能指出我正确的方向,我将不胜感激!如果我使用 PHP 或其他东西来执行此处理,显然会容易得多,但是因为我试图让它成为 Spiceworks 中的嵌入式报告,所以我必须在单个 SQLite 查询中完成所有这些操作。