将VARCHAR转换为VARBINARY


17

我一直将昂贵的运行查询及其查询计划记录在一个表中,以使我们能够监视性能趋势并确定需要优化的领域。

但是,到了查询计划占用太多空间的地步(因为我们针对每个查询存储整个计划)。

因此,我试图通过将QueryPlanHash和QueryPlan提取到另一个表来规范化现有数据。

CREATE TABLE QueryPlans
(
    QueryPlanHash VARBINARY(25),
    QueryPlan XML,
    CONSTRAINT PK_QueryPlans PRIMARY KEY
    (
      QueryPlanHash
    )
);

因为query_plan_hashin 的定义sys.dm_exec_query_stats是一个二进制字段(并且我将定期插入新数据),所以我VARBINARY在新表中使用了该数据类型。

但是,下面的插入失败...

INSERT INTO QueryPlans
    ( QueryPlanHash, QueryPlan )
SELECT queryplanhash, queryplan
FROM
(
    SELECT 
      p.value('(./@QueryPlanHash)[1]', 'varchar(20)') queryplanhash,
      QueryPlan,
      ROW_NUMBER() OVER (PARTITION BY p.value('(./@QueryPlanHash)[1]', 'varchar(20)') ORDER BY DateRecorded) rownum
    FROM table
    CROSS APPLY QueryPlan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple[@QueryPlanHash]') t(p)
) data
WHERE rownum = 1

....有错误

Implicit conversion from data type varchar to varbinary is not allowed. Use the CONVERT function to run this query.

问题是查询计划哈希已经是二进制格式,但是作为VARCHAR存储在XML查询计划中,例如

0x9473FBCCBC01AFE

和CONVERT to BINARY给出了完全不同的值

0x3078393437334642434342433031414645

我尝试将XQuery选择中的值定义更改为二进制,但随后未返回任何值。

如何0x9473FBCCBC01AFE从XML查询计划中提取的值作为VARBINARY,而不是VARCHAR

Answers:


28

从字符串转换时,如果希望保留相同的二进制值,则需要使用特定的样式。否则,SQL Server会尝试使用与编码'bob'或相同的方式对字符串进行编码'frank'

就是说,您的输入字符串看起来不正确-缺少一个字节或一个字节太多。如果我删除尾随,这工作正常E

SELECT CONVERT(VARBINARY(25), '0x9473FBCCBC01AF', 1);
------------ the ,1 is important ---------------^^^

结果为二进制:

----------------
0x9473FBCCBC01AF

1
啊,那,1是我所缺少的。这比我预期的要容易!谢谢!
马克·辛金森

不确定丢失/多余的字节。在我拥有的2666条记录中,有183条没有通过TRY_CONVERT
马克·辛金森

可能需要在字符计数为奇数的任何字符串后附加一个字符(例如0)。这会更改值,但始终应以相同的方式更改相同的值(并且我不怀疑您会在0或0的情况下发生任何冲突)。
亚伦·伯特兰

那不是错误吗?xml中的queryplanhash显式设置为该值...当然TRY_CONVERT,a BINARY不应返回NULL
Mark Sinkinson 2014年

通过将表中保存的值与xml进行比较,实际上是缺少前导0。因此,该值应为0x09473FBCCBC01AF。我可以通过简单的替换来解决这些问题,但我敢肯定这是一个错误...
马克·辛金森

0

如何从XML查询计划中提取0x9473FBCCBC01AFE的值作为VARBINARY而不是VARCHAR?

我遇到了使用HeidiSQL在CASD表上查询的问题,并使用fn_varbintohexstr()解决了,像这样:

SELECT master.dbo.fn_varbintohexstr(table.hexfield) FROM table;

使用HeidiSQL时,该值错误,例如“ 0x3F3F3F3F3F3F3F3F3F3F”,并变为正确的错误,例如“ 0x158B1DB75616484695684007CE98E21C”。

OBS:自MSSQL 2008起有效!希望能帮助到你!


2
请注意fn_varbintohexstr() 此处提到的使用注意事项。
Erik
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.