在两个单独的表中用 T-SQL 解析 XML

Parsing XML with T-SQL in two separate tables

使用 SQL Server 2012 并尝试在我的数据库中将 XML 解析为 2 个单独的 table。通常 1 table 就足够了,但在这种情况下不行。我的 XML 结构如下(我不能改变它的结构,我已经收到了)

  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
  <podjetje id="" storitev="" uporabnik="" ts="" opis_storitve="">
  <izdelki>
  <izdelek st="1">
      <izdelekID>ID</izdelekID> 
      <ean>EAN CODE</ean> 
      <izdelekIme>PRODUCT NAME</izdelekIme> 
      <url>WEBSITE</url> 
      <kratkiopis>SHORT DESCRIPTION</kratkiopis> 
      <opis>DESCRIPTION</opis> 
      <dodatneLastnosti>ATTRIBUTES</dodatneLastnosti> 
      <slikaVelika>BIG PICTURE URL</slikaVelika> 
      <dodatneSlike>
          <dodatnaSlika1>EXTRA IMAGE URL</dodatnaSlika1> 
          <dodatnaSlika2>EXTRA IMAGE URL2</dodatnaSlika2> 
          <dodatnaSlika3>EXTRA IMAGE URL3</dodatnaSlika3> 
      </dodatneSlike>
  </izdelek>
  </izdelki>
  </podjetje>

要将此 XML 插入 table,我使用 SQL 批量插入

SET @SQLString = 'INSERT INTO tmpImport(XmlCol)

SELECT * 
FROM OPENROWSET(BULK ''' + @ImportFileName + ''', SINGLE_BLOB, ERRORFILE = ''' + @BulkLoadFilePath + ''') AS x '

EXECUTE (@SQLString)

我可以毫无问题地处理大部分数据。当我到达节点 "dodatneSlike" 时,我 运行 遇到了一些问题。这个想法是,每篇文章都有一些图片。主图在节点"slikaVelika"中,我可以将它插入到我的table中。 node"dodatneSlike"的子节点多了图片。这给我带来了问题,因为我必须将这些额外的图片插入到单独的 table 中(从节点 "slikaVelika" 插入图片也会有所帮助,但我想如果不可能的话我可以绕过它) . table 没什么特别的,只是来自节点 "izdelekID" 的文章 ID 和来自 "dodatneSlike" 的图片。

问题是,我永远不知道会有多少节点("dodatnaSlika1"、"dodatnaSlika2"、...)。可能有 1, 10, 0....

所以我的问题是如何从 "dodatnaSlika" 个节点获取值?

尝试在 SQL 服务器中使用本机 XQuery 支持!比笨重的旧 OPENROWSET 东西容易得多....

您可以尝试这样的操作:

DECLARE @input XML = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
  <podjetje id="" storitev="" uporabnik="" ts="" opis_storitve="">
  <izdelki>
  <izdelek st="1">
      <izdelekID>ID</izdelekID> 
      <ean>EAN CODE</ean> 
      <izdelekIme>PRODUCT NAME</izdelekIme> 
      <url>WEBSITE</url> 
      <kratkiopis>SHORT DESCRIPTION</kratkiopis> 
      <opis>DESCRIPTION</opis> 
      <dodatneLastnosti>ATTRIBUTES</dodatneLastnosti> 
      <slikaVelika>BIG PICTURE URL</slikaVelika> 
      <dodatneSlike>
          <dodatnaSlika1>EXTRA IMAGE URL</dodatnaSlika1> 
          <dodatnaSlika2>EXTRA IMAGE URL2</dodatnaSlika2> 
          <dodatnaSlika3>EXTRA IMAGE URL3</dodatnaSlika3> 
      </dodatneSlike>
  </izdelek>
  </izdelki>
  </podjetje>'

SELECT
    izdelek_st = @input.value('(/podjetje/izdelki/izdelek/@st)[1]', 'int'),
    izdelekID = @input.value('(/podjetje/izdelki/izdelek/izdelekID)[1]', 'varchar(50)'),
    ean = @input.value('(/podjetje/izdelki/izdelek/ean)[1]', 'varchar(50)'),

    XC.value('local-name(.)', 'varchar(50)'),
    XC.value('(.)[1]', 'varchar(50)')
FROM 
    @input.nodes('/podjetje/izdelki/izdelek/dodatneSlike/*') AS XT(XC)

这将为您提供 <dodatneSlike> 下的所有子节点 - 无论有多少 - 并且它会为您提供 节点名称 ,以及 节点值.

更新:假设你有多个<izdelek>节点,那么你可以改用这个查询:

SELECT
    izdelek_st = @input.value('(/podjetje/izdelki/izdelek/@st)[1]', 'int'),

    izdelekID = xc1.value('(izdelekID)[1]', 'varchar(50)'),
    ean = xc1.value('(ean)[1]', 'varchar(50)'),

    XC2.value('local-name(.)', 'varchar(50)'),
    XC2.value('(.)[1]', 'varchar(50)')
FROM 
    @input.nodes('/podjetje/izdelki/izdelek') AS XT1(XC1)
CROSS APPLY
    xc1.nodes('dodatneSlike/*') AS XT2(XC2)