1

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.

Aside from the XML, the query itself is simple:

    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. This is what the XML looks like:

    <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? and then tried declaring a XML namespace with the following query:

       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. Thank you in advance for any help.

0

1 Answer 1

2

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.
  • Use of the text() in the XPath expressions is for performance reasons.

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

+-----------+-------------+-------------------------+
| firstName |    Title    |     GamingIssueDate     |
+-----------+-------------+-------------------------+
| John      | IT Director | 2021-02-18 12:00:00.000 |
+-----------+-------------+-------------------------+
Sign up to request clarification or add additional context in comments.

1 Comment

You don't need all that in my opinion. If the data is stored in an xml column, you could simply access the value with this [xml_column_name].value('(//Title) [1]', 'varchar(max)') [Title]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.