การแปลง 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 Query Plan เช่น

0x9473FBCCBC01AFE

และแปลงเป็นไบนารีให้ค่าที่ต่างกันโดยสิ้นเชิง

0x3078393437334642434342433031414645

ฉันพยายามเปลี่ยนนิยามของค่าใน XQuery select เป็น binary แต่แล้วมันก็คืนค่าใด ๆ

ฉันจะแยกค่า0x9473FBCCBC01AFEจากแผนแบบสอบถาม XML เป็น a VARBINARYแทนที่จะเป็นVARCHARอย่างไร

คำตอบ:


28

คุณต้องใช้สไตล์ที่เฉพาะเจาะจงเมื่อคุณคาดว่าจะเก็บค่าไบนารีเดียวกันเมื่อแปลงจากสตริง มิฉะนั้น SQL Server พยายามที่จะเข้ารหัสสตริงแบบเดียวกับที่มันจะเข้ารหัสหรือ'bob''frank'

ที่กล่าวว่าสตริงที่ป้อนของคุณดูไม่ถูกต้อง - มีไบต์ที่ขาดหายไปหรือหนึ่งไบต์มากเกินไป วิธีนี้ใช้ได้ผลถ้าฉันวางส่วนต่อท้ายE:

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

ผลลัพธ์คือไบนารี:

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

1
อา,1เป็นสิ่งที่ฉันขาดหายไป นั่นง่ายกว่าที่ฉันคาดไว้! ขอบคุณ!
Mark Sinkinson

ไม่แน่ใจเกี่ยวกับไบต์ที่ขาดหายไป / พิเศษ ในบันทึก 2666 ฉันมี 183 ที่ล้มเหลวTRY_CONVERT
Mark Sinkinson

อาจต้องผนวกอักขระ (พูด, 0) ให้กับสตริงใด ๆ ที่มีจำนวนอักขระแปลก นั่นเปลี่ยนค่า แต่ควรเปลี่ยนค่าเดียวกันเสมอในลักษณะเดียวกัน (และฉันไม่สงสัยว่าคุณจะมีการชนกันที่มีหรือไม่มี 0)
Aaron Bertrand

นั่นไม่ใช่ข้อผิดพลาดหรือไม่? queryplanhash ในรูปแบบ XML ที่มีการกำหนดอย่างชัดเจนค่าที่ ... แน่นอนTRY_CONVERTไปBINARYไม่ควรกลับNULL
มาร์ค Sinkinson

จากการเปรียบเทียบค่าที่บันทึกไว้ในตารางของฉันกับ xml จริง ๆ แล้วมันคือการนำ 0 ที่หายไป ดังนั้นค่าควรเป็น 0x09473FBCCBC01AF ฉันสามารถแก้ไขเหล่านั้นขึ้นด้วยง่ายแทนที่ แต่ฉันแน่ใจว่ามันเป็นข้อผิดพลาด ...
มาร์ค Sinkinson

0

ฉันจะแยกค่า 0x9473FBCCBC01AFE จากแผนแบบสอบถาม XML เป็น VARBINARY แทนที่จะเป็น VARCHAR ได้อย่างไร

ฉันเผชิญบางอย่างเช่นนั้นโดยใช้ HeidiSQL เพื่อสอบถามในตาราง CASD และแก้ไขด้วยfn_varbintohexstr ()เช่นนี้

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

ด้วย HeidiSQL ค่านั้นผิดเช่น '0x3F3F3F3F3F3F3F3F' และถูกต้องเช่น '0x158B1DB75616484695684007CE98E21C'

OBS: ทำงานได้ตั้งแต่ MSSQL 2008! หวังว่ามันจะช่วย!


2
หมายเหตุ: คำเตือนที่จะใช้กล่าวถึงที่นี่fn_varbintohexstr()
Erik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.