简体   繁体   English

从SQL Server中的一列解析XML数据

[英]Parse XML data from a column in SQL Server

I'm trying to put together a report for a badge program.我正在尝试为徽章计划整理一份报告。 Some the data for custom fields we created are stored in a single column in the table as XML. I need to return a couple of the items in there to the report and am having a hard time getting the proper syntax to get it to parse out.我们创建的自定义字段的一些数据存储在表中的单个列中,为 XML。我需要将其中的几个项目返回到报告中,并且很难获得正确的语法来解析它.

Aside from the XML, the query itself is simple:除了 XML 之外,查询本身很简单:

    SELECT
  Person1.firstName
  ,Person1.lastName
  ,Person1.idNumber
  ,Person1.idNumber2
  ,Person1.idNumber3
  ,Person1.status
  ,Person1.customdata
FROM
  Person1

the field "customdata" is the XML field that I need to pull Title, and 2 different dates out of.字段“customdata”是我需要提取标题的 XML 字段,以及 2 个不同的日期。 This is what the XML looks like:这是 XML 的样子:

    <person1_7:CustomData xmlns:person1_7="http://www.badgepass.com/Person1_7">
    <Title>IT Director</Title>
    <Gaming_x0020_Level>Level 1</Gaming_x0020_Level>
    <Gaming_x0020_Issue_x0020_Date>2021-02-18T12:00:00Z</Gaming_x0020_Issue_x0020_Date>
    <Gaming_x0020_Expire_x0020_Date>2022-02-18T12:00:00Z</Gaming_x0020_Expire_x0020_Date>
    <Betting_x0020_Level>Level 1</Betting_x0020_Level>
    <Betting_x0020_Issue_x0020_Date>2021-02-18T12:00:00Z</Betting_x0020_Issue_x0020_Date>
    <Betting_x0020_Expire_x0020_Date>2022-02-18T12:00:00Z</Betting_x0020_Expire_x0020_Date>
    <BadgeType>Dual Employee</BadgeType>
    <Gaming_x0020_Status>TEMP</Gaming_x0020_Status>
    <Betting_x0020_Status>TEMP</Betting_x0020_Status>
    </person1_7:CustomData>

I have tried a couple of different methods trying to follow the advice from How to query for Xml values and attributes from table in SQL Server?我尝试了几种不同的方法,试图遵循如何从 SQL 服务器中的表中查询 Xml 值和属性的建议? and then tried declaring a XML namespace with the following query:然后尝试使用以下查询声明 XML 命名空间:

       WITH XMLNAMESPACES ('http://www.badgepass.com/Person1_7' as X)
SELECT
  Person1.firstName
  ,Person1.lastName
  ,Person1.idNumber
  ,Person1.idNumber2
  ,Person1.idNumber3
  ,Person1.status
  ,Person1.customdata.value('(/X:person1_7:customdata/X:Title)[1]', 'varchar(100)') AS Title
FROM
  Person1

So far all of my results keep returning "XQuery [Person1.customData.value()]: ")" was expected. " I'm assuming I have a syntax issue that I'm overlooking as I've never had to manipulate XML with SQL before.到目前为止,我所有的结果都在预期中返回“XQuery [Person1.customData.value()]:”)”。”我假设我有一个语法问题,我忽略了,因为我从来没有操作过 XML与 SQL 之前。 Thank you in advance for any help.预先感谢您的任何帮助。

Please try the following solution.请尝试以下解决方案。

Notable points:值得注意的地方:

  • XQuery .nodes() method establishes a context so you can access any XML element right away without long XPath expressions. XQuery .nodes()方法建立了一个上下文,因此您可以立即访问任何 XML 元素,而无需长 XPath 表达式。
  • Use of the text() in the XPath expressions is for performance reasons.在 XPath 表达式中使用text()是出于性能原因。

SQL SQL

-- DDL and sample data population, start
DECLARE @person1 TABLE (firstname varchar(50), customdata xml);
INSERT INTO @person1(firstname, customdata) VALUES
('John', '<person1_7:CustomData xmlns:person1_7="http://www.badgepass.com/Person1_7">
    <Title>IT Director</Title>
    <Gaming_x0020_Level>Level 1</Gaming_x0020_Level>
    <Gaming_x0020_Issue_x0020_Date>2021-02-18T12:00:00Z</Gaming_x0020_Issue_x0020_Date>
    <Gaming_x0020_Expire_x0020_Date>2022-02-18T12:00:00Z</Gaming_x0020_Expire_x0020_Date>
    <Betting_x0020_Level>Level 1</Betting_x0020_Level>
    <Betting_x0020_Issue_x0020_Date>2021-02-18T12:00:00Z</Betting_x0020_Issue_x0020_Date>
    <Betting_x0020_Expire_x0020_Date>2022-02-18T12:00:00Z</Betting_x0020_Expire_x0020_Date>
    <BadgeType>Dual Employee</BadgeType>
    <Gaming_x0020_Status>TEMP</Gaming_x0020_Status>
    <Betting_x0020_Status>TEMP</Betting_x0020_Status>
</person1_7:CustomData>');
-- DDL and sample data population, end

WITH XMLNAMESPACES ('http://www.badgepass.com/Person1_7' as person1_7)
SELECT firstName
  , c.value('(Title/text())[1]', 'VARCHAR(100)') AS Title
  , c.value('(Gaming_x0020_Issue_x0020_Date/text())[1]', 'DATETIME') GamingIssueDate
FROM @person1
    CROSS APPLY customdata.nodes('/person1_7:CustomData') AS t(c);

Output Output

+-----------+-------------+-------------------------+
| firstName |    Title    |     GamingIssueDate     |
+-----------+-------------+-------------------------+
| John      | IT Director | 2021-02-18 12:00:00.000 |
+-----------+-------------+-------------------------+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM