5

I am attempting to parse an XML field which is part of the SCOM 2007 Data Warehouse database and have found many examples which show similar scenarios of achieving this however nothing appears to return values, typically when I run the query it errors.

Here is an example, one row of a thousand or so I need to run this against, where I want to pull in the values England and UK (the GUID's which comprise the tag are consistent for each data type so never change and can be used to query etc). Of course each row has a different city and country code and that is what I want to capture.

The table name is dbo.ManagedEntityProperty and the column name is PropertyXML

<Root>
            <Property Guid="AFB4F9E6-BF48-1737-76AD-C9B3EC325B97">192.168.1.0</Property>
            <Property Guid="5C324096-D928-76DB-E9E7-E629DCC261B1">WASPDC01.LIV10.Local</Property>
            <Property Guid="96981E2D-DECF-7CB7-DEC5-5C52046B68A6">192.168.1.0</Property>
            <Property Guid="FA3887C3-F274-306A-867C-37105A190F78">England</Property>
            <Property Guid="61AA7309-595F-576E-337E-E9335E5CA773">255.255.255.0</Property>
            <Property Guid="F8ABF27F-A169-6FCD-1862-C06F1DB4BF24">UK</Property>
            <Property Guid="B832B2DE-A649-60A1-AC13-06F1EC601E5F">Active</Property>
</Root>

Any advice or guidance? I attempted to implement advice as per SQL Server query xml attribute for an element value but I am still very much in my SQL XML query infancy and have never had to do something like this before.

Community
  • 1
  • 1
user2215800
  • 53
  • 1
  • 1
  • 3

1 Answers1

3

Try something like this:

-- declare your two GUIDs that you're interested in
DECLARE @GuidCountry UNIQUEIDENTIFIER
SET @GuidCountry = 'FA3887C3-F274-306A-867C-37105A190F78'

DECLARE @GuidCountryCode UNIQUEIDENTIFIER 
SET @GuidCountryCode = 'F8ABF27F-A169-6FCD-1862-C06F1DB4BF24'

;WITH ListOfAllProperties AS
(
    SELECT 
        ID,   -- or whatever uniquely identifies a single row in your table
        PropertyGuid = XProp.value('@Guid', 'uniqueidentifier'),
        PropertyValue = XProp.value('(.)', 'varchar(100)')
    FROM 
        dbo.ManagedEntityProperty
    CROSS APPLY
        PropertyXML.nodes('/Root/Property') AS XTbl(XProp)
)
SELECT *
FROM ListOfAllProperties
WHERE PropertyGuid IN (@GuidCountry, @GuidCountryCode)

This basically enumerates all <Property> nodes in your table into individual rows, and when grabs the two items you're interested in from those rows

Update: if you need to show these two values as separate columns, you'd have to use something like this:

SELECT 
    ID,
    CountryCode = PropertyXML.value('(/Root/Property[@Guid=sql:variable("@GuidCountryCode")]/text())[1]', 'varchar(100)'),
    CountryName = PropertyXML.value('(/Root/Property[@Guid=sql:variable("@GuidCountry")]/text())[1]', 'varchar(100)')
FROM 
    dbo.ManagedEntityProperty
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Brilliant, really fast response there and it works great. Only had to tweak the declare part as I'm using SQL 2005, but that's my fault because I didn't tell you the version :) – user2215800 Mar 27 '13 at 14:30
  • If I wanted to display the output, the two XML values in the same row but different columns, how would I go about that? I am trying to get my head around the '(.)' and how I could change the script behaviour from this to perhaps target each GUID separately instead of enumerating all then filtering. Know what I mean? – user2215800 Mar 27 '13 at 16:06