将 XML 数据插入到具有多个节点的 SQL 表中

Posted

技术标签:

【中文标题】将 XML 数据插入到具有多个节点的 SQL 表中【英文标题】:Inserting XML data into SQL Table with multiple nodes 【发布时间】:2020-10-19 11:29:11 【问题描述】:

所以我有以下 XML:

     <NIACList>
<NIAC>
        <Number></Number>
        <SubmissionDate></SubmissionDate>
        <ExpirationDate  />
        <IssuerIDNO></IssuerIDNO>
        <IssuerName></IssuerName>
        <SuspensionPeriod/>
        <Cessation>
          <Basis  />
          <Date  />
        </Cessation>
        <Merchant>
          <IDNx></IDNx>
          <Name></Name>
          <Address>
            <Region></Region>
            <Locality></Locality>
            <Street></Street>
            <House></House>
            <Block  />
            <Flat  />
            <Phone  />
            <Fax  />
            <Email  />
          </Address>
        </Merchant>
        <CommercialUnit>
          <IDNx  />
          <Name  />
          <Type></Type>
          <Area></Area>
          <Location></Location>
          <Address>
            <Region></Region>
            <Locality></Locality>
            <Street></Street>
            <House></House>
            <Block  />
            <Flat  />
          </Address>
          <Activities>
            <Activity>
              <Code></Code>
              <Name></Name>
            </Activity>
          </Activities>
          <Goods>
            <Good>
              <Name></Name>
            </Good>
          </Goods>
          <WorkProgram  />
          <PublicSupplyUnit>
            <Capacity  />
            <TerraceCapacity  />
          </PublicSupplyUnit>
          <TradingAlcohol  />
          <TradingBeer  />
          <TradingTobaccoProducts  />
          <AmbulatoryTrading  />
          <MobileUnitTrading></MobileUnitTrading>
          <MobileUnit>
            <Type  />
            <Length  />
            <Width  />
            <Height  />
          </MobileUnit>
          <CommercialApparatusTrading></CommercialApparatusTrading>
          <CommercialApparatus>
            <Count  />
            <Length  />
            <Width  />
            <Height  />
          </CommercialApparatus>
        </CommercialUnit>
        <Modifications  />
      </NIAC>
</NIACList>

这是我创建的表的脚本:

    create table Merchant (
        IdMerchant int identity  primary key,
        IDNX nvarchar(max) null,
        Name nvarchar(max) null,
        WorkProgram datetime2 null,
        IdAddress int 
        );
    create table Address (
    IdAddress int identity  primary key,
    Region nvarchar(60) null,
    Locality nvarchar(50) null,
    Street nvarchar (60) null,
    House nvarchar (10) null,
    Block nvarchar (10) null,
    Flat nvarchar(10) null,
    Phone nvarchar(30) null,
    Fax nvarchar(60) null,
    Email nvarchar(60) null
    
    );

create table CommercialUnit (
IDCommercialUt int identity primary key,
IDNx nvarchar(90) null,
Name nvarchar(90) null,
Type nvarchar(90) null,
Area int null,
Location nvarchar(50) null,
TerraceCapacity float null,
TradingAlcohol bit null,
TradingBeer bit null,
TradingTobaccoProducts bit null,
AmbulatoryTrading bit null,
MobileUnitTrading bit null,
CommercialApparatusTrading bit null,
IDActivities int ,
IDGoods int ,
IDMobileUnit int ,
IDCommercial int ,
IDPSU int 
);

我不太擅长 XML,但问题是: 我有表MerchantAddress。问题是,节点地址重复了2 次(在MerchantCommercialUnit 节点中),并且有不同的数据。我的任务是以某种方式指定插入,所以我要插入的数据将分为两类,一类用于Merchant节点,另一类用于CommercialUnit。插入地址后,记录必须与MerchantCommercialUnit的外键链接( IdAddress),所以数据也会插入到这里。

我尝试插入数据,但它是从 CommercialUnit 节点插入的。 下面是插入代码:

INSERT INTO Address(Region,Locality,Street,House,Block,Flat,Phone,Fax,Email)
        SELECT 
        Region=c.value('Region[1],','nvarchar(60)'),
        Locality=c.value('Locality[1],','nvarchar(50)') ,
        Street=c.value('Street[1],','nvarchar(60)') ,
        House=c.value('House[1],','nvarchar(10)') ,
        Block=c.value('Block[1],','nvarchar(10)') ,
        Flat=c.value('Flat[1],','nvarchar(10)') ,
        Phone=c.value('Phone[1],','nvarchar(30)') ,
        Fax=c.value('Fax[1],','nvarchar(60)') ,
        Email=c.value('Email[1],','nvarchar(60)') 
    FROM @xml.nodes('/NIACList/NIAC/Merchant/Address') Address(c)

【问题讨论】:

您的查询准确地提取了/NIACList/NIAC/Merchant/Address 节点数据。有什么问题? 问题是,我想同时从具有 Address 节点的 Merchant 节点和也具有 Address 节点的 CommercialUnit 节点获取数据,并将其插入到我的 Address 表中(从两个方面),但它只取自 CommercialUnit,而不是您提到的 Merchant。在我这样做之后,我想通过连接来自 Address 的记录将数据插入到 Merchant 和 CommercialUnit 表中。 【参考方案1】:

您需要依次执行四个INSERT 语句:

    INSERT INTO Address ...(针对商家),并将其新生成的身份值捕获到变量中。 INSERT INTO Merchant ... 并使用上面的变量。 INSERT INTO Address ...(用于 CommercialUnit),并捕获其新 将标识值生成到变量中。 INSERT INTO CommercialUnit ... 并使用上面的变量。

概念 SQL

DECLARE @IdAddress INT;

-- Merchant
INSERT INTO Address ...

-- get last IDENTITY value for the Address table
SET @IdAddress = SCOPE_IDENTITY();

INSERT INTO Merchant ...

-- CommercialUnit
INSERT INTO Address ...

-- get last IDENTITY value for the Address table
SET @IdAddress = SCOPE_IDENTITY();

INSERT INTO CommercialUnit ...

【讨论】:

【参考方案2】:

一种方法是使用cross apply。如果您只需要不同的地址,

SELECT distinct t.*             
    FROM @xml.nodes('/NIACList/NIAC') niac(n)
    cross apply (
      select  Region=c.value('Region[1],','nvarchar(60)'),
        Locality=c.value('Locality[1],','nvarchar(50)') ,
        Street=c.value('Street[1],','nvarchar(60)') ,
        House=c.value('House[1],','nvarchar(10)') ,
        Block=c.value('Block[1],','nvarchar(10)') ,
        Flat=c.value('Flat[1],','nvarchar(10)') ,
        Phone=c.value('Phone[1],','nvarchar(30)') ,
        Fax=c.value('Fax[1],','nvarchar(60)') ,
        Email=c.value('Email[1],','nvarchar(60)') 
        from niac.n.nodes('Merchant/Address') ma(c)
      union
      select  Region=c.value('Region[1],','nvarchar(60)'),
        Locality=c.value('Locality[1],','nvarchar(50)') ,
        Street=c.value('Street[1],','nvarchar(60)') ,
        House=c.value('House[1],','nvarchar(10)') ,
        Block=c.value('Block[1],','nvarchar(10)') ,
        Flat=c.value('Flat[1],','nvarchar(10)') ,
        Phone=c.value('Phone[1],','nvarchar(30)') ,
        Fax=c.value('Fax[1],','nvarchar(60)') ,
        Email=c.value('Email[1],','nvarchar(60)') 
        from niac.n.nodes('CommercialUnit/Address') ua(c)
    ) t 

【讨论】:

以上是关于将 XML 数据插入到具有多个节点的 SQL 表中的主要内容,如果未能解决你的问题,请参考以下文章

将每个 xml 节点插入到 sql server 2008 表中

将 XML 多个嵌套节点插入 SQL 表

如何设置“以属性的形式将xml数据插入到SQL Server2008数据库的表中”的存储过程

将多个表中的数据插入到一个表中

SSIS一次将具有起始范围的递增ID插入多个表中

使用 CodeIgniter 框架将数据插入到具有外键的多个表中