Devolver todos los nodos XML importan en SQL Server
-
20-09-2019 - |
Pregunta
He importado un documento XML en SQL Server, ahora estoy tratando de importar varias partes en diferentes tablas. Cuando uso la siguiente consulta que sólo devuelve una fila de hotel_facilities, tengo que devolver todos los hotel_facilities con el hotel_ref.
DECLARE @Details xml
SET @Details = '<hotels>
<hotel>
<hotel_ref>105</hotel_ref>
<hotel_facilities>
<id>2</id>
<name>Disabled Facilities</name>
<id>4</id>
<name>24 Hour Reception</name>
<id>12</id>
<name>Restaurant</name>
</hotel_facilities>
</hotel>
</hotels>'
SELECT tab.col.value('../hotel_ref[1]','varchar(100)') AS 'hotel_ref',
tab.col.value('./id[1]','varchar(100)') AS 'HotelFacilityID',
tab.col.value('./name[1]','varchar(100)') AS 'HotelFacilityName'
FROM @Details.nodes('//hotels/hotel/hotel_facilities') AS tab(col)
Solución
Estoy de acuerdo con marc_s El XML no tiene un buen esquema.
Lo más cerca que pude conseguir es:
SELECT tab.col.value('./hotel_ref[1]','varchar(100)') AS 'hotel_ref',
fac.value('(.)[1]','varchar(100)') AS 'HotelFacilityID',
ROWID=IDENTITY(int,1,1)
into #facilitiesid
FROM @Details.nodes('/hotels/hotel') AS tab(col)
cross apply col.nodes('.//id') a(fac)
SELECT tab.col.value('../hotel_ref[1]','varchar(100)') AS 'hotel_ref',
fac.value('(.)[1]','varchar(100)') AS 'HotelFacilityName',
ROWID=IDENTITY(int,1,1)
into #facilitiesnames
FROM @Details.nodes('//hotels/hotel/hotel_facilities') AS tab(col)
cross apply col.nodes('.//name') a(fac)
select i.hotel_ref, HotelFacilityID, HotelFacilityName
from #facilitiesid i
inner join #facilitiesnames n
on i.rowid = n.rowid
Otros consejos
Su XML se estructura un poco raro - el <hotel_facilities>
no contiene un adecuado "sub-entidad" que se podría enumerar más ......
Si sus instalaciones serían envueltos en un elemento <facility>....</facility>
, fácilmente se podría enumerar eso.
<hotel_facilities>
<facility>
<id>2</id>
<name>Disabled Facilities</name>
</facility>
<facility>
<id>4</id>
<name>24 Hour Reception</name>
</facility>
<facility>
<id>12</id>
<name>Restaurant</name>
</facility>
</hotel_facilities>
Sin embargo, con su configuración actual, creo que va a en apuros para encontrar una buena solución ....