Chuyển đổi VARCHAR sang VARBINARY


17

Tôi đã ghi nhật ký các truy vấn đang chạy đắt tiền, cùng với các gói truy vấn của họ, trong một bảng để cho phép chúng tôi theo dõi các xu hướng về hiệu suất và xác định các khu vực cần tối ưu hóa.

Tuy nhiên, đã đến lúc các kế hoạch truy vấn chiếm quá nhiều không gian (vì chúng tôi đang lưu trữ toàn bộ kế hoạch đối với từng truy vấn).

Do đó, tôi đang cố gắng bình thường hóa dữ liệu hiện có bằng cách trích xuất QueryPlanHash và QueryPlan sang một bảng khác.

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

Vì định nghĩa của query_plan_hashin sys.dm_exec_query_statslà trường nhị phân (và tôi sẽ thường xuyên chèn dữ liệu mới), tôi đã sử dụng VARBINARYcho loại dữ liệu trong bảng mới của mình.

Tuy nhiên, phần chèn bên dưới không thành công ...

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

.... với lỗi

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

Vấn đề là các băm của kế hoạch truy vấn đã ở định dạng nhị phân, tuy nhiên được lưu trữ dưới dạng VARCHAR trong Kế hoạch truy vấn XML, vd

0x9473FBCCBC01AFE

và CHUYỂN ĐỔI để BINary mang lại một giá trị hoàn toàn khác

0x3078393437334642434342433031414645

Tôi đã thử thay đổi định nghĩa giá trị trong XQuery select thành nhị phân, nhưng sau đó nó không trả về giá trị nào.

Làm cách nào để trích xuất giá trị 0x9473FBCCBC01AFEtừ một kế hoạch truy vấn XML dưới dạng VARBINARYchứ không phải là một VARCHAR?

Câu trả lời:


28

Bạn cần sử dụng một kiểu cụ thể khi bạn muốn giữ cùng một giá trị nhị phân khi chuyển đổi từ một chuỗi. Mặt khác, SQL Server cố mã hóa chuỗi giống như cách mã hóa 'bob'hoặc 'frank'.

Điều đó nói rằng, chuỗi đầu vào của bạn trông không chính xác - có một byte bị thiếu hoặc một byte quá nhiều. Điều này hoạt động tốt nếu tôi thả dấu vết E:

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

Kết quả là nhị phân:

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

1
Ah, đó ,1là những gì tôi đã thiếu. Điều đó dễ dàng hơn tôi mong đợi! Cảm ơn!
Mark Sinkinson

Không chắc chắn về byte bị thiếu / thêm. Trong 2666 hồ sơ tôi có, có tới 183 lần thất bạiTRY_CONVERT
Mark Sinkinson

Có thể cần nối thêm một ký tự (giả sử 0) vào bất kỳ chuỗi nào có số ký tự lẻ. Điều đó thay đổi giá trị, nhưng phải luôn thay đổi cùng một giá trị theo cùng một cách (và tôi không nghi ngờ bạn sẽ có bất kỳ va chạm nào có hoặc không có 0).
Aaron Bertrand

Đó không phải là một lỗi? Các queryplanhash trong xml được một cách rõ ràng thiết lập để giá trị đó ... Chắc chắn một TRY_CONVERTđến một BINARYkhông nên trở lạiNULL
Đánh dấu Sinkinson

Từ việc so sánh các giá trị được lưu trong bảng của tôi với xml, nó thực sự là một số 0 đứng đầu. Vì vậy, giá trị nên là 0x09473FBCCBC01AF. Tôi có thể sửa những lỗi đó bằng một REPLACE đơn giản, nhưng tôi chắc chắn đó là một lỗi ...
Mark Sinkinson

0

Làm cách nào để tôi trích xuất giá trị của 0x9473FBCCBC01AFE từ một kế hoạch truy vấn XML dưới dạng VARBINARY, thay vì VARCHAR?

Tôi đã đối mặt với một cái gì đó tương tự bằng cách sử dụng HeidiSQL để truy vấn trên các bảng CASD và giải quyết bằng fn_varbintohexstr () , như thế này:

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

Với HeidiSQL, giá trị sai như '0x3F3F3F3F3F3F3F3F' và trở thành chính xác như '0x158B1DB75616484695684007CE98E21C'.

OBS: Hoạt động kể từ MSSQL 2008! Hy vọng nó giúp!


2
Lưu ý hãy cẩn thận khi sử dụng fn_varbintohexstr() được đề cập ở đây .
Erik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.