Iterative Abfrage für räumliche Aufzeichnungen

Ich habe folgende Abfrage in SQL server erstellt

declare @x XML set @x='<Dataset_Extent> <EXTENT_TYPE>Bounding_Polygon</EXTENT_TYPE> <Vertex> <LON>66.91292909247741</LON> <LAT>30.27001012181008</LAT> <X>299232</X> <Y>3350549</Y> <COL>1</COL> <ROW>1</ROW> </Vertex> <Vertex> <LON>66.99456841960638</LON> <LAT>30.27128639618252</LAT> <X>307089.5</X> <Y>3350549</Y> <COL>15715</COL> <ROW>1</ROW> </Vertex> <Vertex> <LON>66.99700791329992</LON> <LAT>30.1509623521339</LAT> <X>307089.5</X> <Y>3337207.5</Y> <COL>15715</COL> <ROW>26683</ROW> </Vertex> <Vertex> <LON>66.91546772378466</LON> <LAT>30.14969219541345</LAT> <X>299232</X> <Y>3337207.5</Y> <COL>1</COL> <ROW>26683</ROW> </Vertex> <Center> <LON>66.9549932872921</LON> <LAT>30.21048776638499</LAT> <X>303160.75</X> <Y>3343878.25</Y> <COL>7858</COL> <ROW>13342</ROW> </Center> </Dataset_Extent>'; declare @wkt varchar(8000); select @wkt=CONVERT(varchar(7000),@x.query('distinct-values( for $lon in /Dataset_Extent/Vertex/LON/text() for $lat in /Dataset_Extent/Vertex/LAT/text() return ($lon cast as xs:string?,$lat cast as xs:string?,",")) ')); --concatenate the word POLYGON set @wkt='POLYGON(('+@wkt +'))'; print @wkt 

Dies gibt mir folgende Ausgabe:

 POLYGON((66.91292909247741 66.99456841960638 30.27128639618252 66.99700791329992 66.91546772378466 30.27001012181008,30.1509623521339 30.14969219541345)) 

Jedes Lon / Lat-Paar ist nicht in der richtigen Reihenfolge, ich benötigte die Ausgabe im folgenden Format:

 POLYGON((66.91292909247741 30.27001012181008,66.99456841960638 30.27128639618252,66.99700791329992 30.1509623521339,66.91546772378466 30.14969219541345,66.91292909247741 30.27001012181008)) 

Der Anfangsscheitel Lon / Lat sollte auch am Ende wiederholen, um das Polygon zu schließen.

Was muss ich tun, um die Probleme zu beheben?

das wird den Job machen …

 DECLARE @wkt NVARCHAR(MAX) SELECT @wkt = COALESCE(@wkt + ',' + char(13), '') + concat(convert(varchar, x.query('./LON/text()')),' ', convert(varchar,x.query('./LAT/text()'))) from @x.nodes('/Dataset_Extent/Vertex') as t(x) select @wkt = COALESCE(@wkt + ',' + char(13), '') + concat(convert(varchar, x.query('./LON/text()')),' ', convert(varchar,x.query('./LAT/text()'))) from @x.nodes('/Dataset_Extent/Vertex[1]') as t(x) set @wkt='POLYGON(('+@wkt +'))'; print @wkt 

nicht gerade schön, aber ich konnte nicht herausfinden, wie man den ersten Knoten unterbricht … viel Glück! Ich versuche, xpath so viel wie möglich zu vermeiden, wenn ich kann 🙂

Fetzen Sie das XML auf /Dataset_Extent/Vertex und build Sie die characterfolge mit dem for xml path Trick.

 declare @wkt varchar(8000); set @wkt = 'POLYGON((' + stuff((select ','+TXvalue('(LON/text())[1]', 'varchar(50)')+ ' '+TXvalue('(LAT/text())[1]', 'varchar(50)') from @x.nodes('/Dataset_Extent/Vertex') as T(X) for xml path('')), 1, 1, '')+ ','+@x.value('(/Dataset_Extent/Vertex/LON/text())[1]', 'varchar(50)')+ ' '+@x.value('(/Dataset_Extent/Vertex/LAT/text())[1]', 'varchar(50)')+ '))'; 

Gegen einen Tisch würde es so aussehen.

 select 'POLYGON((' + stuff((select ','+TXvalue('(LON/text())[1]', 'varchar(50)')+ ' '+TXvalue('(LAT/text())[1]', 'varchar(50)') from X.XMLData.nodes('/Dataset_Extent/Vertex') as T(X) for xml path('')), 1, 1, '')+ ','+X.XMLData.value('(/Dataset_Extent/Vertex/LON/text())[1]', 'varchar(50)')+ ' '+X.XMLData.value('(/Dataset_Extent/Vertex/LAT/text())[1]', 'varchar(50)')+ '))' from XMLFiles as X;