Sql-server – Compare value from xml node that contains decimal

sql serversql server 2014xml

I need to compare the values of two different XML nodes for a record stored on SQL Server 2014.

Here is the contents of my XML column that I will be using:

<Document>
   <PolicyId>0</PolicyId>
   <ChangeAmount>1.4-</ChangeAmount>
   <PolicyTerm>
       <OutstandingBalance>35.04+</OutstandingBalance>
   </PolicyTerm>
   <OriginalCollectionAmount>36.44+</OriginalCollectionAmount>
</Document> 

Here is my SQL statement that is not working:

SELECT *
FROM   Table 
WHERE  QueueName ='.\private$\CollectionActivityPosted'
AND    Payload.value('(/Document/TransType)[1]', 'nvarchar(20)') = 'C'
AND    (Payload.value('(/Document/OutstandingBalance)[1]', 'nvarchar(20)') 
       <> 
       (Payload.value('(/Document/OriginalCollectionAmount)[1]', 'nvarchar(20)')))

I am expecting my query to get a hit based on the OutstandingBalance not being equal to the OriginalCollectionAmount but it doesn't.

Best Answer

It looks like you've got the wrong path in your where predicate. If I do this, it works:

IF OBJECT_ID(N'dbo.x', N'U') IS NOT NULL
DROP TABLE dbo.x;
CREATE TABLE dbo.x
(
    xm xml
);
INSERT INTO dbo.x (xm)
SELECT N'<Document>
   <PolicyId>0</PolicyId>
  <ChangeAmount>1.4-</ChangeAmount>
  <PolicyTerm>
    <OutstandingBalance>35.04+</OutstandingBalance>
  </PolicyTerm>
  <OriginalCollectionAmount>36.44+</OriginalCollectionAmount>
</Document>';

SELECT x.xm.value('(/Document/PolicyTerm/OutstandingBalance)[1]', 'nvarchar(20)')
FROM dbo.x
╔══════════════════╗
║ (No column name) ║
╠══════════════════╣
║ 35.04+           ║
╚══════════════════╝

Testing:

SELECT *
FROM dbo.x
WHERE (x.xm.value('(/Document/PolicyTerm/OutstandingBalance)[1]', 'nvarchar(20)') <>
     (x.xm.value('(/Document/OriginalCollectionAmount)[1]', 'nvarchar(20)')))
╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                                       xm                                                                                                        ║
╠═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ <Document><PolicyId>0</PolicyId><ChangeAmount>1.4-</ChangeAmount><PolicyTerm><OutstandingBalance>35.04+</OutstandingBalance></PolicyTerm><OriginalCollectionAmount>36.44+</OriginalCollectionAmount></Document> ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

In your code, Payload.value('(/Document/OutstandingBalance)[1]', 'nvarchar(20)') should be Payload.value('(/Document/PolicyTerm/OutstandingBalance)[1]', 'nvarchar(20)')