Données XML déchiquetage dans des tables
-
17-09-2020 - |
Question
J'ai un problème dans lequel je dois déchiqueter plusieurs ensembles de données XML de plusieurs fournisseurs dans un seul ensemble de tables en mappant divers éléments dans les sources de mes propres tables. Je peux faire cela juste bien lorsque je rassemble les informations de haut niveau, mais certaines de mes informations sont dans une collection, telles que les catégories. Ma première étape consiste simplement à extraire les données de XML et à la mettre en quelques tables, puis à la prochaine étape consiste à fusionner les données dans mes tables réelles.
Mes données XML ressemble à ceci:
<ArrayOfApiNewItemDetailInfo>
<ApiNewItemDetailInfo>
<categories>
<ApiNavCategoryInfo>
<count></count>
<id></id>
<name></name>
<selected></selected>
</ApiNavCategoryInfo>
<ApiNavCategoryInfo>
<count></count>
<id></id>
<name></name>
<selected></selected>
</ApiNavCategoryInfo>
</categories>
<item_id></item_id>
<product_id></product_id>
</ApiNewItemDetailInfo>
<ArrayOfApiNewItemDetailInfo>
Je veux déchiqueter ces données dans une table avec ID de produit, ID d'élément et ID de catégorie, lorsque plusieurs catégories peuvent être affectées à un seul produit
Tout d'abord, j'ai ma table de photos
CREATE TABLE [dbo].[DataDictionary](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Provider] [varchar](50) NOT NULL,
[XmlColumn] [varchar](100) NOT NULL,
[Datatype] [varchar](100) NOT NULL,
[DestinationColumn] [varchar](100) NOT NULL
)
Dans ce tableau, j'ai ces enregistrements:
88 Categories product_id int ProviderProductId
89 Categories item_id int ItemId
93 Categories categories/ApiNavCategoryInfo/id int CategoryId
Maintenant, j'ai une instruction SQL qui tire dans le dictionnaire de données pour mon fournisseur et déchiquetant les données dans une table.
CREATE TABLE #SQLWork (Row_Id INT IDENTITY,SQL varchar(500))
INSERT #SQLWork (SQL) VALUES ('DROP TABLE TempCategories')
INSERT #SQLWork (SQL) VALUES ('SELECT ')
INSERT #SQLWork (SQL) SELECT 'Categories.value(''' + XmlColumn + '[1]''' + ',''' + Datatype + ''') as ' + DestinationColumn + ', '
FROM DataDictionary WHERE UPPER(Provider) = 'CATEGORIES'
UPDATE #SQLWork SET SQL = REPLACE(SQL,', ','') WHERE row_id = @@IDENTITY
INSERT #SQLWork (SQL) VALUES (' INTO TempCategories ')
INSERT #SQLWork (SQL) VALUES (' FROM RawDetails CROSS APPLY Data.nodes(''' + '//ArrayOfApiNewItemDetailInfo/ApiNewItemDetailInfo' + ''') as NewTable(Categories)')
DECLARE @SQL nvarchar(max)
select @SQL = coalesce(@SQL + ' ',' ') + Sql from #SQLWork Order By Row_Id
--SELECT @SQL
exec sp_executesql @sql
drop table #Sqlwork
La déclaration SQL générée ressemble à ceci:
DROP TABLE TempCategories
SELECT
Categories.value('product_id[1]','int') as ProviderProductId,
Categories.value('item_id[1]','int') as ItemId,
Categories.value('categories/ApiNavCategoryInfo/id[1]','int') as CategoryId
INTO
TempCategories
FROM
RawDetails
CROSS APPLY
Data.nodes('//ArrayOfApiNewItemDetailInfo/ApiNewItemDetailInfo') as NewTable(Categories)
Quand je cours ma déclaration, j'obtiens l'erreur:
xquery [rawdetails.data.value ()]: 'valeur ()' nécessite un singleton (ou Séquence vide), trouvé Opérande de type 'XDT: UNTYPEDATOMIQUE *'
Des idées?
merci.
La solution
J'ai découvert que mes chemins étaient faux.
j'ai changé
Data.nodes('//ArrayOfApiNewItemDetailInfo/ApiNewItemDetailInfo') as NewTable
à
Data.nodes('//ArrayOfApiNewItemDetailInfo/ApiNewItemDetailInfo/categories/ApiNavCategoryInfo') as NewTable
et j'ai changé mes enregistrements avec cette
88 Categories ../../product_id int ProviderProductId
89 Categories ../../item_id int ItemId
93 Categories id int CategoryId
Et cela a fonctionné.