2012-04-18 114 views
0

我想在Spiceworks中使用SQLite查询编写自定义报告。这份报告将取得我硬盘驱动器的序列号,不幸的是,这些序列号是以几种不同的方式存储的,这取决于机器上的Windows和WMI版本。带列数据的SQLite X'...'表示法

三种常见的例子(这是足以让实际问题)如下:

实际编号: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' 

这表明X'....'符号样式在给定完全字面数字(202020%线)时会转换为W -DXW05CAT94843的正确(但倒退)结果。但是,我需要找到一种方法来对列pd.serial中的实际数据做同样的事情,但我找不到方法。

我最初的想法是,如果我可以构建X'...'表示法的字符串表示形式,那么cast()可能会对它进行评估。但正如你所看到的那样,结果只是吐出了X'3030303030303030313131343330423137454342'而不是预期的00000000111430B17ECB。这意味着级联工作正常,但我无法找到一种方式来评估它,因为十六进制与手动测试用例中的一样。

我一直在使用googling来查看是否只有一些我缺少的语法,但最接近的是我使用||运算符进行了这种连接。

编辑:最后我只想能有一个简单的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查询中完成此操作。

+0

它一定是迟到了,但是你能简化一下,或者只是在最后重新提出这个问题吗?我这样说是因为我不明白你在问什么。 – 2012-04-18 16:34:32

+0

那么,我想要做的就是能够把X'pd.serial'并让它理解我正在尝试做什么。不幸的是,因为pd.serial(包含数据的列)被包装在单引号中,查询将其视为文字字符串。这有助于澄清吗? – 2012-04-18 16:40:57

回答

0

X'...'是sqlite中的二进制表示。如果这些值是字符串,那么您可以直接使用它们。

这应该是一个开始:

sqlite> select X'3030303030303030313131343330423137454342'; 
00000000111430B17ECB 
sqlite> select ltrim(X'3030303030303030313131343330423137454342','0'); 
111430B17ECB 

我希望让你在正确的道路上。

+0

对,我一直在做手动显示,并按照我想要的方式转换数据。 (很好的提示摆脱了前面的零,顺便说一句!)但我有300+条目在我的表中,我需要得到他们每个人的二进制表示,并输出结果。 – 2012-04-18 17:23:51