Comment convertir de BLOB de géométrie SQL Server à autre chose?

14

J'ai un fichier de données CSV d'un tiers qui est une table SQL Server exportée. Ils ont simplement fait un select * from fooet sorti le résultat dans un fichier texte et l'ont envoyé.

Dans leur table se trouve une colonne de type Geometry, donc dans mon texte brut j'ai quelque chose comme "0xE610000010C47 ...", etc. Pour le moment je l'ai chargé dans une table dans SQL Server en tant que nvarchar.

Je m'attendais à pouvoir revenir en arrière dans un champ de géométrie de mon côté, mais cela ne semble pas être si facile. STGeomFromWKBne fonctionne pas car ce n'est pas un WKB. Je ne peux pas convertir la chaîne en géométrie car elle se plaint que ce n'est pas un WKT.

Alors, est-il possible d'obtenir cette valeur dans SQL Server comme s'il s'agissait d'un BLOB de géométrie normal? Puis-je dire à SQL Server de le traiter comme tel?

J'ai trouvé ce lien qui a au moins aidé à répondre à ma question sur ce qui se trouve dans SQL Server, mais ne m'a pas permis de tout faire: quel est le format du type de données Geometry de SQLServer 2008

Peter
la source
Il ressemble à WKB (Well Known Binary) il y a une description Esri edndoc.esri.com/arcsde/9.1/general_topics/… mais le format est OGC (Open Geospatial Consortium) Je pense qu'il serait un peu plus facile d'utiliser le builtin fonctions comme décrit sur le lien fourni ou sur l'un répertorié msdn.microsoft.com/en-AU/library/bb933960.aspx Je pense que le problème réside dans le fait que vous avez importé une chaîne hexadécimale en tant que texte et non en fait en tant que binaire - mais je peux n'y aide pas, je n'ai pas grand-chose à voir avec le backend de SQL. Vous pourriez peut-être demander à Super User ou DB Admin sur stackexchange.
Michael Stimson
@Peter avez-vous déjà trouvé une de ces solutions pour votre problème?
DPSSpatial

Réponses:

9

Lorsque vous importez les données dans SQL Server, placez-les dans une colonne VARBINARY (MAX). Vous devriez ensuite être en mesure de CAST cela en tant que géométrie ou géographie selon les besoins. Vous devrez faire attention à ce que la chaîne 0xE6 ... ne soit pas modifiée lors de l'importation.

Une autre option consiste à effectuer une requête dynamique pour obtenir la sélection. J'ai mis quelques exemples de conversion ci-dessous.

-- 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)')
MickyT
la source
6

En s'appuyant sur la réponse de @ MickyT, puisque vous allez avoir une table avec vos valeurs déjà dans WKB (ou comme nous l'appelons), vous voudriez écrire sql qui convertira tous les enregistrements en géométrie, plutôt que d'avoir à déclarer une variable, etc. etc.

Donc, si vous commencez avec une simple table temporaire qui répliquerait le WKB dans un enregistrement, cela ressemblerait à ceci:

select 0x3D0B0000010C80BAE380AE064841005149CD6EFD3941 as wkb

Maintenant, si vous traitez cela comme une table temporaire et enveloppez du SQL autour de lui, vous avez une colonne avec le WKB là-dedans et vous pouvez le convertir en varbinary comme suggéré ci-dessus:

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

temp.wkb peut être la colonne de votre plus grande table contenant les valeurs WKB du CSV

Enfin, utilisez la méthode décrite par MickyT et convertissez le varbinary en géométrie:

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

Ce qui renvoie une géométrie et un résultat spatial:

entrez la description de l'image ici

EDIT où le SRID est-il déclaré? Comme MickyT a répondu, c'est dans le binaire, et vous pouvez envelopper 1 requête SQL supplémentaire autour de là pour tester:

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

qui donne, et est correct dans mon exemple, 2877 (plan d'état colorado):

entrez la description de l'image ici

DPSSpatial
la source
1
Le SRID est intégré au binaire Geometry. Le binaire fourni n'est pas WKB, mais la représentation binaire SQL Servery réelle de la géométrie.
MickyT
@MickyT ah oui! Je posterai un extrait supplémentaire pour tester ... Merci !!!
DPSSpatial
Serait-il possible d'ajouter une colonne Géométrie à la table d'origine et de mettre à jour cette colonne avec la Géométrie?
Peter Horsbøll Møller
1
@ PeterHorsbøllMøller Je pense que c'est la bonne décision ... une fois converti. J'y travaillerai et posterai plus tard.
DPSSpatial du
3

Affiche originale ici, lorsque j'ai essayé de terminer l'inscription, elle n'a pas lié la connexion à la publication d'origine. En tous cas....

Merci pour votre aide! Je voterai pour chaque réponse une fois que je pourrai et peut-être que si je peux comprendre comment lier ce compte et celui d'origine, je peux marquer une réponse. De plus, après vos pointeurs, je ne peux pas croire que j'ai manqué d'utiliser CONVERTau lieu de CAST. Cela rend beaucoup plus facile.

Je pense que mon problème principal était d'obtenir la "chaîne" binaire brute à quelque chose que je pourrais utiliser. Voici un exemple de la façon dont je l'ai résolu:

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
user57679
la source
Cela semble bon!!! C'est bien d'avoir tout cela documenté ... ça vous sera utile un jour!
DPSSpatial du
cela s'est avéré utile - un collègue de notre service de BI a indépendamment trouvé ce message et l'a utilisé pour obtenir SQL Server Integration Services (SSIS) pour faire passer la géométrie entre les serveurs, ce qui à ce stade ne se trouve pas nativement dans SSIS !! !
DPSSpatial