代码之家  ›  专栏  ›  技术社区  ›  Josh

将XML数据分解到表中

  •  0
  • Josh  · 技术社区  · 15 年前

    我有一个问题,我必须通过将源中的各种元素映射到我自己的表,将多个提供程序中的多个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的表。

    首先,我有我的数据字典表

    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()”需要一个singleton(或 空序列),找到类型的操作数 'xdt:非类型化*'

    有什么想法吗?

    谢谢。

    1 回复  |  直到 15 年前
        1
  •  0
  •   Josh    15 年前

    我发现我走错了路。

    我变了

    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 
    

    这很管用。

    推荐文章