将XML数据分解为表

时间:2010-07-19 20:34:01

标签: xml tsql sql-server-2008 shred

我有一个问题,我必须通过将源中的各种元素映射到我自己的表,将多个提供者的多个xml数据集分成一组表。当我收集顶级信息时,我可以做到这一点,但我的一些信息是在一个集合中,例如类别。我的第一步是从XML中提取数据并将其放入几个表中,然后下一步是将数据合并到我的真实表中。

我的XML数据如下所示:

<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>

如果可以将多个类别分配到单个产品,我想将此数据分解为包含产品ID,商品ID和类别ID的表格

首先,我有我的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
)

在此表中,我有以下记录:

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

现在,我有一个sql语句,它为我的提供者提取数据字典,并将数据分解为一个表。

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

生成的sql语句如下所示:

 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)

当我运行我的陈述时,我收到错误:

  

XQuery [RawDetails.Data.value()]:   'value()'需要一个单身(或   空序列),找到类型的操作数   'xdt:untypedAtomic *'

有什么想法吗?

感谢。

1 个答案:

答案 0 :(得分:0)

我发现我的路径错了。

我改变了

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

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

我用这个

改变了我的记录
88 Categories ../../product_id int ProviderProductId 
89 Categories ../../item_id int ItemId 
93 Categories id int CategoryId 

这很有效。