0

我想itemnumber从 XML 数据中提取列。但是,在 XML 文件中,每行有超过 1 个值(项目编号)。(每行可能有大约 100 个项目编号)

我的查询效果很好,但由于我必须进行大量子查询才能从 XML 中提取所有数据,所以它太慢了

子查询看起来像这样

SELECT RIGHT(LEFT(Cast(x.data AS XML).value ('(table/id/text())[1]','varchar(100)'),37),36)   AS id, 
Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[9]','VARCHAR(255)')   AS 'item', 
Cast(x.data AS XML).value ('(//column[@name="Batchnummer"]/@value)[9]','VARCHAR(255)') AS Batch, 
Cast(x.data AS XML).value('(//column[@name="Aantal"]/@value)[9]','INT')                AS Aantal 
             FROM   synergy..xmldata x (nolock) 
             WHERE  Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[9]','VARCHAR(255)') IS NOT NULL

现在这很好用,但我必须使用Union all大约 100 次才能提取所有数据

有没有更简单的方法来做到这一点?

这就是完整查询的样子(仅供参考,我使用了Union all3 次语句,如果我想让它工作,我必须复制/粘贴 100 次并更改值 amount /@value)[xxxx]

SELECT    XMLDATA.id , 
      XMLDATA.item , 
      XMLDATA.batchnummer , 
      XMLDATA.aantal , 
      y.freetextfield_02 
FROM     ( 
             SELECT RIGHT(LEFT(Cast(x.data AS XML).value ('(table/id/text())[1]','varchar(100)'),37),36)   AS id, 
                    Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[1]','VARCHAR(255)')   AS 'item', 
                    Cast(x.data AS XML).value ('(//column[@name="Batchnummer"]/@value)[1]','VARCHAR(255)') AS Batch, 
                    Cast(x.data AS XML).value('(//column[@name="Aantal"]/@value)[1]','INT')                AS Aantal
             FROM   synergy..xmldata x (nolock) 
             WHERE  Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[1]','VARCHAR(255)') IS NOT NULL 
             UNION ALL 
             SELECT RIGHT(LEFT(Cast(x.data AS XML).value ('(table/id/text())[1]','varchar(100)'),37),36)   AS id, 
                    Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[2]','VARCHAR(255)')   AS 'item', 
                    Cast(x.data AS XML).value ('(//column[@name="Batchnummer"]/@value)[2]','VARCHAR(255)') AS Batch, 
                    Cast(x.data AS XML).value('(//column[@name="Aantal"]/@value)[2]','INT')                AS Aantal
             FROM   synergy..xmldata x (nolock) 
             WHERE  Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[2]','VARCHAR(255)') IS NOT NULL 
             UNION ALL 
             SELECT RIGHT(LEFT(Cast(x.data AS XML).value ('(table/id/text())[1]','varchar(100)'),37),36)   AS id, 
                    Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[3]','VARCHAR(255)')   AS 'item', 
                    Cast(x.data AS XML).value ('(//column[@name="Batchnummer"]/@value)[3]','VARCHAR(255)') AS Batch, 
                    Cast(x.data AS XML).value('(//column[@name="Aantal"]/@value)[3]','INT')                AS Aantal 
             FROM   synergy..xmldata x (nolock) 
             WHERE  Cast(x.data AS XML).value ('(//column[@name="Artikelen"]/@value)[3]','VARCHAR(255)') IS NOT NULL 
                ) XMLDATA 
LEFT JOIN synergy..absences y (nolock) 
ON        y.id = XMLDATA.id 
WHERE     y. freetextfield_02 IS NOT NULL 
AND       type IN ('126', 
               '129') 

这就是 XML 的样子:

<table>
<id>{351CE2EE-59E8-43B0-B95B-81A24A2C037E}</id>
<rows>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="2" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="3" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="4" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="5" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="3.46331132.NL" type="System.String" />
    <column name="Batchnummer" value="190259" type="System.String" />
    <column name="Aantal" value="10" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="14" type="System.Int32" />
  </columns>
  </row>
  </rows>
  <key>DefaultKey</key>
  <total>0</total>
  <AddOnKey>0</AddOnKey>
  <data />
  <parameters />
  </table>

这就是我从DATASET XML IMAGETABLE 列中提取 xml 的数据集的样子Data

4

1 回答 1

1

您需要使用nodes在数据集中为每个columns节点创建一行。然后您可以将其视为数据集:

DECLARE @XML xml = '<table>
<id>{351CE2EE-59E8-43B0-B95B-81A24A2C037E}</id>
<rows>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="2" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="3" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="4" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="101445.A.FF" type="System.String" />
    <column name="Batchnummer" value="PR1900002366" type="System.String" />
    <column name="Aantal" value="1" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="5" type="System.Int32" />
  </columns>
</row>
<row>
  <columns>
    <column name="Artikelen" value="3.46331132.NL" type="System.String" />
    <column name="Batchnummer" value="190259" type="System.String" />
    <column name="Aantal" value="10" type="System.Int32" />
    <column name="Opmerkingen" value="retour" type="System.String" />
    <column name="Magazijn" value="" type="System.String" />
    <column name="Reden" value="" type="System.String" />
    <column name="DefaultKey" value="14" type="System.Int32" />
  </columns>
  </row>
  </rows>
  <key>DefaultKey</key>
  <total>0</total>
  <AddOnKey>0</AddOnKey>
  <data />
  <parameters />
  </table>';

SELECT V.X.value('(/table/id/text())[1]','varchar(255)') AS id,
       r.c.value('(./column[@name="Artikelen"]/@value)[1]', 'varchar(255)') AS item,
       r.c.value('(./column[@name="Batchnummer"]/@value)[1]', 'varchar(255)') AS Batch,
       r.c.value('(./column[@name="Aantal"]/@value)[1]', 'varchar(255)') AS Aantal
FROM (VALUES (@XML)) V (X)
     CROSS APPLY V.X.nodes('table/rows/row/columns') r(c);
于 2020-06-10T09:17:15.303 回答