Измельчение XML-данных в таблицы - PullRequest
0 голосов
/ 20 июля 2010

У меня есть проблема, из-за которой я должен разделить несколько наборов данных 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>

Я хочу уничтожить эти данные в таблице с идентификатором продукта, идентификатором товара и идентификатором категории, когда несколько категорий могут быть назначены одному продукту

Во-первых, у меня есть таблица 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 голосов
/ 21 июля 2010

Я узнал, что мои пути были неправильными.

Я изменил

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 

И это сработало.

...