วิธีการแปลงจาก SQL Server geometry BLOB เป็นอย่างอื่น?


14

ฉันมีไฟล์ข้อมูล CSV จากบุคคลที่สามซึ่งเป็นตาราง SQL Server ที่ส่งออก พวกเขาเพียงแค่ทำselect * from fooและส่งออกผลลัพธ์ไปยังไฟล์ข้อความและส่งมันไป

ในตารางของพวกเขาคือคอลัมน์ประเภทเรขาคณิตดังนั้นในข้อความดิบของฉันฉันมีบางอย่างเช่น "0xE610000010C47 ... " ฯลฯ ในขณะนี้ฉันได้โหลดมันลงในตารางใน SQL Server เป็น nvarchar

ฉันคาดหวังว่าฉันจะสามารถย้อนกลับไปยังเขตเรขาคณิตในตอนท้ายของฉัน แต่ดูเหมือนจะไม่ง่ายนัก STGeomFromWKBไม่ทำงานเพราะไม่ใช่ WKB ฉันไม่สามารถโยนสตริงเป็นเรขาคณิตเพราะมันบ่นว่าไม่ใช่ WKT

ดังนั้นมีวิธีใดที่ฉันสามารถรับค่านี้ลงใน SQL Server ราวกับว่ามันเป็น Geometry BLOB ปกติหรือไม่? ฉันสามารถบอกให้ SQL Server จัดการกับมันได้หรือไม่

ฉันพบลิงค์นี้ซึ่งช่วยอย่างน้อยตอบคำถามของฉันเกี่ยวกับสิ่งที่อยู่ใน SQL Server แต่ไม่ได้รับฉันไปที่นั่น: รูปแบบของประเภทข้อมูลเรขาคณิตของ SQLServer 2008 คืออะไร


ดูเหมือนว่า WKB (รู้จักกันดีใน Binary) มีคำอธิบาย Esri edndoc.esri.com/arcsde/9.1/general_topics/แต่รูปแบบคือ OGC (Open Geospatial Consortium) ฉันคิดว่ามันจะง่ายกว่านี้ถ้าใช้บิวด์อิน ฟังก์ชั่นตามที่อธิบายไว้ในลิงก์ที่ให้ไว้หรือรายการmsdn.microsoft.com/en-AU/library/bb933960.aspx ที่ระบุไว้ฉันคิดว่าปัญหาอยู่ที่ว่าคุณได้นำเข้าสตริงสตริงฐานสิบหกเป็นข้อความไม่ใช่ตัวจริงไบนารี แต่ฉันสามารถ ช่วยไม่ได้ฉันไม่ได้มีอะไรมากกับแบ็กเอนด์ของ SQL บางทีคุณอาจถาม Super User หรือ DB Admin เกี่ยวกับ stackexchange
Michael Stimson

@ Peter คุณเคยพบวิธีการแก้ปัญหาของคุณหรือไม่?
DPSSpatial

คำตอบ:


9

เมื่อคุณนำเข้าข้อมูลไปยัง SQL Server ให้ใส่ลงในคอลัมน์ VARBINARY (MAX) จากนั้นคุณควรสามารถนำสิ่งนี้เป็นเรขาคณิตหรือภูมิศาสตร์ได้ตามต้องการ คุณจะต้องระมัดระวังว่าสตริง 0xE6 ... จะไม่เปลี่ยนแปลงระหว่างการนำเข้า

ตัวเลือกอื่นคือการทำแบบสอบถามแบบไดนามิกเพื่อรับการเลือก ฉันวางตัวอย่างการแปลงสองสามข้อไว้ด้านล่าง

-- As a varchar and binary
DECLARE @NV AS NVARCHAR(MAX) = '0xE610000001040E0000002AA57BA76F5446C027B8FD971024654007517714795446C00C42473D1624654094CFCDE3795446C0D3F576B91624654068507E9C7A5446C0D7BE805E18246540F2FC444A7C5446C0E93DDF6019246540B4CA4C697D5446C0D5DF5C0D1A2465401A0923AC7C5446C08183DE3F1A2465407599E1907B5446C0E2A8818B1A24654058B4805A7A5446C0A70261DE1A24654089729F5C775446C072080BDD1B2465401AAC24A8745446C057CB10FE1C2465403D16A5446E5446C05A20FEE21A246540658BA4DD685446C00907FFA3172465402AA57BA76F5446C027B8FD971024654001000000020000000001000000FFFFFFFF0000000003' 
DECLARE @NB AS VARBINARY(MAX) = 0xE610000001040E0000002AA57BA76F5446C027B8FD971024654007517714795446C00C42473D1624654094CFCDE3795446C0D3F576B91624654068507E9C7A5446C0D7BE805E18246540F2FC444A7C5446C0E93DDF6019246540B4CA4C697D5446C0D5DF5C0D1A2465401A0923AC7C5446C08183DE3F1A2465407599E1907B5446C0E2A8818B1A24654058B4805A7A5446C0A70261DE1A24654089729F5C775446C072080BDD1B2465401AAC24A8745446C057CB10FE1C2465403D16A5446E5446C05A20FEE21A246540658BA4DD685446C00907FFA3172465402AA57BA76F5446C027B8FD971024654001000000020000000001000000FFFFFFFF0000000003

-- Failing conversions
SELECT CAST(@NV AS Geometry)
SELECT CAST(CAST(@NV AS VARBINARY(MAX)) AS Geometry)
-- Correct conversion
SELECT CAST(@NB AS Geometry)
EXEC('SELECT CAST(' + @NV + ' AS Geometry)')

6

การสร้างคำตอบของ @ MickyT เนื่องจากคุณจะมีตารางที่มีค่าของคุณนั่งอยู่ใน WKB (หรืออะไรก็ตามที่เราเรียกมันว่า) คุณต้องการเขียน sql ที่จะแปลงระเบียนทั้งหมดเป็นเรขาคณิตแทนที่จะต้อง ประกาศตัวแปร ฯลฯ ฯลฯ

ดังนั้นหากคุณเริ่มต้นด้วยตารางชั่วคราวที่จะทำซ้ำ WKB ในหนึ่งเร็กคอร์ดมันจะมีลักษณะดังนี้:

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

ตอนนี้ถ้าคุณทำเช่นนั้นเป็นตารางชั่วคราวและล้อม SQL ไว้รอบ ๆ คุณมีคอลัมน์ที่มี WKB อยู่ในนั้นและคุณสามารถแปลงมันเป็น varbinary ตามที่แนะนำข้างต้น:

select 
cast(temp.wkb as varbinary(max)) as geombinary
from 
(
select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb
) as temp

โดยที่temp.wkbสามารถเป็นคอลัมน์ในตารางขนาดใหญ่ของคุณที่มีค่า WKB จาก CSV

สุดท้ายใช้วิธีที่อธิบายโดย MickyT และแปลง varbinary เป็นเรขาคณิต:

select 
cast(geomconvert.geombinary as geometry) as geom
 from (
select 
cast(temp.wkb as varbinary(max)) as geombinary
from 
(
select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb
) as temp
) as geomconvert

ซึ่งส่งกลับรูปทรงเรขาคณิตและผลลัพธ์เชิงพื้นที่:

ป้อนคำอธิบายรูปภาพที่นี่

แก้ไข SRID ได้รับการประกาศที่ไหน? ดังที่ MickyT ตอบมันอยู่ในรูปแบบไบนารี่และคุณสามารถรวมข้อความค้นหา sql เพิ่มเติมอีก 1 รายการเพื่อทดสอบ:

select top 1 getsrid.geom.STSrid from (

select 
cast(geomconvert.geombinary as geometry) as geom
 from (
select 
cast(temp.wkb as varbinary(max)) as geombinary
from 
(
select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb
) as temp
) as geomconvert

) as getsrid

ซึ่งให้ผลและถูกต้องในตัวอย่างของฉัน 2877 (ระนาบ colorado):

ป้อนคำอธิบายรูปภาพที่นี่


1
SRID นั้นสร้างไว้ในไบนารีเรขาคณิต ไบนารีที่ให้มาไม่ใช่ WKB แต่เป็นตัวแทน SQL Servery ไบนารีจริงของเรขาคณิต
MickyT

@MickyT อ่าใช่! ฉันจะโพสต์อีกหนึ่งตัวอย่างเพื่อทดสอบ ... ขอบคุณ !!!
DPSSpatial

เป็นไปได้ไหมที่จะเพิ่มคอลัมน์เรขาคณิตลงในตารางต้นฉบับและอัปเดตคอลัมน์นั้นด้วยเรขาคณิต
Peter HorsbøllMøller

1
@ PeterHorsbøllMøllerฉันคิดว่านั่นเป็นการเดินทางที่ถูกต้อง ... เมื่อมันกลับใจใหม่ ฉันจะทำงานในเรื่องนั้นและโพสต์ในภายหลัง
DPSSpatial

3

โปสเตอร์ดั้งเดิมที่นี่เมื่อฉันพยายามสมัครให้เสร็จก็ไม่ได้เชื่อมโยงการลงชื่อเข้าใช้กับโพสต์ดั้งเดิม อย่างไรก็ตาม....

ขอบคุณสำหรับความช่วยเหลือ! ฉันจะ upvote แต่ละคำตอบเมื่อฉันสามารถและถ้าฉันสามารถหาวิธีการเชื่อมโยงบัญชีนี้และคำตอบเดิมที่ฉันสามารถทำเครื่องหมายคำตอบได้ นอกจากนี้หลังจากที่ตัวชี้ของคุณฉันไม่สามารถเชื่อว่าฉันพลาดใช้แทนCONVERT CASTมันทำให้ง่ายขึ้นมาก

ฉันคิดว่าปัญหาหลักของฉันคือการได้รับ "สตริง" ไบนารีดิบเป็นสิ่งที่ฉันสามารถใช้ได้ นี่คือตัวอย่างของวิธีที่ฉันแก้ไข:

DECLARE @data TABLE (
  ID nvarchar(1024),
  ImportedGeometry nvarchar(max),
  FinalGeometry geometry
  )

  INSERT INTO @data (ID, ImportedGeometry) values ('1', '0xE6100000010C4703780B24B855C061C3D32B65093540')
  INSERT INTO @data (ID, ImportedGeometry) values ('2', '0xE6100000010C96438B6CE7D359C0BD5296218E853440')

select 
d.ID,
d.ImportedGeometry,
CONVERT(varbinary(max), d.ImportedGeometry, 1) as ConvertedGeometryBin,
(cast(CONVERT(varbinary(max), d.ImportedGeometry, 1) as geometry)) as FinalGeometry
from @data d

UPDATE @data
SET FinalGeometry = (cast(CONVERT(varbinary(max), ImportedGeometry, 1) as geometry))

select 
d.ID,
d.FinalGeometry,
d.FinalGeometry.STAsText(),
d.FinalGeometry.STSrid
from @data d

ดูดี!!! ดีที่มีเอกสารทั้งหมดนี้ ... มันจะมีประโยชน์ในหนึ่งวัน!
DPSSpatial

สิ่งนี้มีประโยชน์ - เพื่อนแผนก BI ของเราพบโพสต์นี้เป็นอิสระและใช้มันเพื่อให้บริการการรวมเซิร์ฟเวอร์ SQL (SSIS) ผ่านเรขาคณิตไปมาระหว่างเซิร์ฟเวอร์ซึ่ง ณ จุดนี้ไม่พบใน SSIS !! !
DPSSpatial
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.