Domanda

Ho un problema in cui devo brandire più set di dati XML da più fornitori in un singolo set di tabelle mappando vari elementi nelle fonti alle mie tabelle. Posso farlo bene solo quando raccogliamo le informazioni di alto livello, ma alcune delle mie informazioni sono in una collezione, come le categorie. Il mio primo passo è solo per estrarre i dati fuori da XML e inserirlo in poche tabelle e quindi il passo successivo è unire i dati nelle mie tabelle reali.

I miei dati XML sembrano questo:

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

Voglio brandire questi dati in una tabella con ID prodotto, ID elemento e ID di categoria, quando possono essere assegnate più categorie a un singolo prodotto

Prima di tutto, ho il mio tavolo Datadtionary

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

In questa tabella ho questi record:

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

Ora, ho un'istruzione SQL che tira nel dizionario dei dati per il mio provider e brandisce i dati in una tabella.

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'istruzione SQL che viene generata è simile:

 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 eseguo la mia dichiarazione, ottengo l'errore:

.

xquery [rawdetails.data.value ()]: 'Valore ()' richiede un singleton (o Sequenza vuota), trovato operando di tipo 'XDT: UNTYREPATOMIC *'

Qualche idea?

Grazie.

È stato utile?

Soluzione

Ho scoperto che i miei percorsi erano sbagliati.

Ho cambiato

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

a

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

E ho cambiato i miei record con questo

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

e quello ha funzionato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top