2013-05-16 2 views
1

У меня есть XML, который мне нужно вставить в две таблицы базы данных. Вторая таблица (TblSales) должна содержать PK первого (TblDetails.Id).SQL Server: манипулирование сложным xml в таблицах

я могу вставить данные в этих таблицах, используя XQuery, но я не могу придумать хороший способ получить рК TblDetails в FK (DetailsId) из TblSales?

Я использую SQL Server 2005.

DECLARE @xml XML 
SET @xml = 
N'<Details> 
    <Detail> 
     <Sub>SubjectName 1</Sub> 
     <Data>DataName 1</Data> 
     <Sales> 
      <Sale> 
       <Name>Name 1</Name> 
      </Sale> 
      <Sale> 
       <Name>Name 11</Name> 
      </Sale> 
      <Sale> 
       <Name>Name 111</Name> 
      </Sale> 
     </Sales> 
    </Detail> 
    <Detail> 
     <Sub>SubjectName 2</Sub> 
     <Data>DataName 2</Data> 
     <Sales> 
      <Sale> 
       <Name>Name 2</Name> 
      </Sale> 
      <Sale> 
       <Name>Name 22</Name> 
      </Sale> 
      <Sale> 
       <Name>Name 222</Name> 
      </Sale> 
     </Sales> 
    </Detail> 
</Details>' 

-- Details 

IF object_id('TblDetails') is not null 
    drop table TblDetails 

create table TblDetails ( 
    Id int identity not null primary key, 
    Sub nvarchar(max), 
    Data nvarchar(max)) 

INSERT INTO TblDetails (
    Sub, 
    Data 
) 
SELECT 
    ParamValues.Detail.value('(Sub)[1]','NVARCHAR(MAX)') AS [Sub], 
    ParamValues.Detail.value('(Data)[1]','NVARCHAR(MAX)') AS [Data] 
FROM 
    @xml.nodes('/Details/Detail') AS ParamValues(Detail) 


-- Sales 

IF object_id('TblSales') is not null 
    drop table TblSales 

create table TblSales ( 
    Id int identity not null primary key, 
    Name nvarchar(max), 
    DetailsId int) -- FK to TblDetails.Id PK 

INSERT INTO TblSales (
    Name, 
    DetailsId 
) 
SELECT 
    ParamValues.Sale.value('(Name)[1]','NVARCHAR(MAX)') AS [Name], 
    1 --Need to get the PK of the newly added row in TblDetails 
FROM 
    @xml.nodes('/Details/Detail/Sales/Sale') AS ParamValues(Sale) 



select * from TblDetails 
select * from TblSales 

ответ

1

Ну, вы могли бы попробовать что-то вроде этого:

-- first insert your rows into "TblDetails" 
INSERT INTO dbo.TblDetails(Sub, Data) 
    SELECT 
     ParamValues.Detail.value('(Sub)[1]','VARCHAR(50)') AS [Sub], 
     ParamValues.Detail.value('(Data)[1]','VARCHAR(50)') AS [Data] 
    FROM 
     @xml.nodes('/Details/Detail') AS ParamValues(Detail) 

-- now, in a second step, use a CTE (Common Table Expression) to get the 
-- inserted data and the new data for TblSales 
;WITH CTE AS 
(
    SELECT 
     ParamValues.Detail.value('(Sub)[1]','VARCHAR(50)') AS [Sub], 
     ParamValues.Detail.value('(Data)[1]','VARCHAR(50)') AS [Data], 
     XTbl.Sale.value('(Name)[1]', 'VARCHAR(50)') AS [Name] 
    FROM 
     @xml.nodes('/Details/Detail') AS ParamValues(Detail) 
    CROSS APPLY 
     ParamValues.Detail.nodes('Sales/Sale') AS XTbl(Sale) 
) 
INSERT INTO dbo.TblSales(Name, DetailsId) 
    SELECT 
     Name, 
     (SELECT TOP 1 ID -- fetch the ID from the TblDetails based on "Sub" and "Data" 
     FROM TblDetails d 
     WHERE d.Sub = CTE.Sub AND d.Data = CTE.DATA)  
    FROM CTE 

Конечно, такой подход только действительно работает, если ваши комбинации (Sub, Data) являются уникальный в TblDetails. Может быть, вам нужно немного подкорректировать это, но, надеюсь, это будет хорошая стартап.

+0

Спасибо, к сожалению, данные в TblDetails не могут быть уникальными. Является ли это общей методикой, используемой для выполнения этого типа процедуры? Другой вариант - добавить дополнительный столбец в таблицу «TblSales», которая будет хранить данные «SalesXml». Затем, когда появляется «Вставить» в «TblDetails», я могу «ВЫХОД» в «INSERTED TblDetails.Id» и «INSERTED TblDetails.SalesXml» во временную таблицу. Но это добавляет дополнительные данные в таблицу, которые необходимы только для этой процедуры. –

+1

@ DanielBillingham: если ваш ('Sub, Data') не может быть уникальным - тогда у вас должно быть что-то еще в исходном XML, с помощью которого вы можете однозначно идентифицировать ** узел' ', иначе это никогда не сработает. , –

Смежные вопросы