2010-07-19 4 views
0

J'ai un problème où je dois détruire plusieurs jeux de données XML de plusieurs fournisseurs en un seul jeu de tables en mappant divers éléments des sources sur mes propres tables. Je peux le faire très bien quand je rassemble les informations de niveau supérieur, 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 à les mettre dans quelques tables, puis l'étape suivante consiste à fusionner les données dans mes tables réelles.Déchiquetage de données XML dans des tables

Mes données ressemble XML 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 identifiant de produit, id article et id catégorie, lorsque plusieurs catégories peuvent être attribuées à un seul produit

Tout d'abord, j'ai ma table DataDictionary

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 je ces documents:

Maintenant, j'ai une instruction SQL qui tire dans le dictionnaire de données pour mon fournisseur et déchiquette 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 

L'instruction SQL qui est généré 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 lance ma déclaration, je reçois l'erreur:

XQuery [RawDetails.Data.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'

Toutes les idées?

Merci.

+0

FYI, le XML n'apparaît pas ... vérifié dans IE et Firefox. – 8kb

Répondre

0

J'ai découvert que mes chemins étaient erronés.

j'ai changé

Data.nodes('//ArrayOfApiNewItemDetailInfo/ApiNewItemDetailInfo') as NewTable 

à

Data.nodes('//ArrayOfApiNewItemDetailInfo/ApiNewItemDetailInfo/categories/ApiNavCategoryInfo') as NewTable 

Et j'ai changé mes dossiers avec ce

88 Categories ../../product_id int ProviderProductId 
89 Categories ../../item_id int ItemId 
93 Categories id int CategoryId 

Et cela a fonctionné.

Questions connexes