如何在T-SQL中使用XML属性作为搜索条件?

时间:2019-03-28 21:44:17

标签: sql-server xml attributes

我有一个SQL Server表:

    CREATE TABLE [dbo].[XMLFiles](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [XML] [xml] NOT NULL,
    [processed] [int] NOT NULL,
    [createtime] [datetime] NOT NULL,
    [handletime] [datetime] NULL,
    [objectId] [varchar](50) NOT NULL,
    [ResultText] [varchar](200) NULL,
    [BatchID] [varchar](50) NOT NULL,
    [Type] [varchar](32) NOT NULL,
    CONSTRAINT [PK_XMLFiles] PRIMARY KEY CLUSTERED 

在此上下文中,有趣的列是XML和BatchID。 BatchID是唯一标识符。我在XML列中的xml数据具有如下部分:

...
            <CLASSIFICATION>
                <CLASS name="Face Mills Indexable" id="TA_MILL_20_20">
                    <ATTRIBUTE id="-45001" name="Tool Description" datatype="STRING">T990 d100 highfeed</ATTRIBUTE>
                    <ATTRIBUTE id="-41210" name="Comments" datatype="STRING"/>
                    <ATTRIBUTE id="-41101" name="Supplier" datatype="STRING"/>
                    <ATTRIBUTE id="-45211" name="Plant" datatype="ENUM">4 Lahti</ATTRIBUTE>
                    <ATTRIBUTE id="160000" name="Machine Tool" datatype="ENUM">BW4 MCR 750</ATTRIBUTE>
                    <ATTRIBUTE id="-45212" name="Machine Group" datatype="ENUM"/>
                    <ATTRIBUTE id="-45210" name="Status" datatype="ENUM"/>
...

假设我对id =“ 160000”的属性值(即第五个属性)感兴趣。我可以通过sql查询获取值:

SELECT
xml.value('(/PLM_PUBLISH_ITEM/ITEMS/ITEM/CLASSIFICATION/CLASS/ATTRIBUTE)[5]','varchar(30)') AS TCODE
FROM XMLFiles
WHERE batchid = '1553762782573'

结果正确:BW4 MCR 750

但是,我不确定这行始终是这里的第五行。因此,我想使用SQL将属性ID用作搜索条件。

类似这样的东西:

SELECT something FROM XMLFiles WHERE BacthID='1553762782573'
AND something = '160000'

如何获得此?我没办法了...

1 个答案:

答案 0 :(得分:1)

您可以使用XPath谓词[@id='160000']来获取属性id的值为160000的节点。

SELECT xml.value('(/PLM_PUBLISH_ITEM/ITEMS/ITEM/CLASSIFICATION/CLASS/ATTRIBUTE[@id=''160000''])[1]','varchar(30)') tcode
       FROM xmlfiles
       WHERE batchid = '1553762782573';

如果您对实际值不感兴趣,而只想选择XML中存在此类元素的行,则也可以使用exist()

SELECT *
       FROM xmlfiles
       WHERE batchid = '1553762782573'
             AND xml.exist('/PLM_PUBLISH_ITEM/ITEMS/ITEM/CLASSIFICATION/CLASS/ATTRIBUTE[@id=''160000'']') <> 0;