Pergunta

Tenho um problema em que devo fragmentar vários conjuntos de dados XML de vários provedores em um único conjunto de tabelas, mapeando vários elementos nas fontes para minhas próprias tabelas.Posso fazer isso muito bem quando estou coletando informações de nível superior, mas algumas das minhas informações estão em uma coleção, como as categorias.Meu primeiro passo é extrair os dados do XML e colocá-los em algumas tabelas e, em seguida, o próximo passo é mesclar os dados em minhas tabelas reais.

Meus dados XML são assim:

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

Quero fragmentar esses dados em uma tabela com ID do produto, ID do item e ID da categoria, quando várias categorias podem ser atribuídas a um único produto

Em primeiro lugar, tenho minha tabela 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
)

Nesta tabela tenho estes registros:

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

Agora, tenho uma instrução sql que extrai o dicionário de dados do meu provedor e fragmenta os dados em uma tabela.

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

A instrução SQL gerada é semelhante a esta:

 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)

Quando executo minha instrução, recebo o erro:

XQuery [RawDetails.Data.value()]:'value ()' requer uma singleton (ou sequência vazia), encontrada operando do tipo 'xdt: não tytypedatomic *'

Alguma ideia?

Obrigado.

Foi útil?

Solução

Descobri que meus caminhos estavam errados.

eu mudei

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

para

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

E eu mudei meus registros com isso

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

E isso funcionou.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top