1

我有一些 XML 需要插入到两个数据库表中。第二个表 ( TblSales) 必须包含第一个 ( TblDetails.Id) 的 PK。

我可以使用 XQuery 将数据插入到这些表中,但我想不出一种将 PKTblDetails放入 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
4

1 回答 1

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. 也许你需要稍微调整一下——但我希望这应该是一个很好的起点!

于 2013-05-16T16:07:34.250 回答