web-dev-qa-db-ja.com

VARCHARからVARBINARYへの変換

パフォーマンスの傾向を監視し、最適化が必要な領域を特定できるように、実行中の高額なクエリとそのクエリプランのログをテーブルに保持しています。

ただし、クエリプランが領域を使いすぎている状態になっています(各クエリに対してプラン全体を格納しているため)。

したがって、QueryPlanHashとQueryPlanを別のテーブルに抽出して、既存のデータを正規化しようとしています。

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

query_plan_hashsys.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.

問題は、クエリプランのハッシュがすでにバイナリ形式であるにもかかわらず、XMLクエリプランにVARCHARとして格納されていることです。

0x9473FBCCBC01AFE

そして、CONVERT to BINARYは完全に異なる値を与えます

0x3078393437334642434342433031414645

XQuery選択の値の定義をバイナリに変更しようとしましたが、値が返されませんでした。

XMLクエリプランから0x9473FBCCBC01AFEの値をVARBINARYではなくVARCHARとして抽出するにはどうすればよいですか?

18
Mark Sinkinson

文字列から変換するときに同じバイナリ値を保持することが予想される場合は、特定のスタイルを使用する必要があります。それ以外の場合、SQL Serverは'bob'または'frank'をエンコードするのと同じ方法で文字列をエンコードしようとします。

そうは言っても、入力文字列は正しくありません。1バイトが不足しているか、1バイトが多すぎます。末尾のEを削除すると、これは正常に機能します:

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

結果はバイナリです:

----------------
0x9473FBCCBC01AF
31
Aaron Bertrand

XMLクエリプランから0x9473FBCCBC01AFEの値をVARCHARではなくVARBINARYとして抽出するにはどうすればよいですか?

私はHeidiSQLを使用してCASDテーブルをクエリするような問題に直面し、次のようにfn_varbintohexstr()で解決しました:

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

HeidiSQLでは、値は「0x3F3F3F3F3F3F3F3F」のように間違っていて、「0x158B1DB75616484695684007CE98E21C」のように正しくなりました。

OBS:MSSQL 2008以降で機能します!それが役に立てば幸い!

0
MMJ