1

I have an XML column in my table and I want to use a value from the XML to filter the rows in my table.

Let table name be: mytable & Let column name be: mycolumn

Sample XML:

<TxMsg>
  <TxCode>sometxt</TxCode>
  <TxType>sometxttype</TxType>
  <Roads>someroads</Roads>
  <VehicleId>QWE123</VehicleId>
...etc
<TxMsg>

How should I query my table such that I can only see rows that contains VehicleId = 'QWE123'?

I am hoping to find solutions like:

SELECT * FROM mytable WHERE mycolumn.(xpath) = 'QWE123'

3 Answers 3

1

You should use exist() in the where clause.

select *
from dbo.mytable as T
where T.mycolumn.exist('/TxMsg/VehicleId/text()[. = "QWE123"]') = 1;

Use sql:variable if you would like to use a variable or a parameter.

declare @VehicleId varchar(6) = 'QWE123';

select *
from dbo.mytable as T
where T.mycolumn.exist('/TxMsg/VehicleId/text()[. = sql:variable("@VehicleId")]') = 1;
Sign up to request clarification or add additional context in comments.

Comments

0

There's a complete prototype of how to do that in my github repository (https://github.com/KELightsey/chamomile/blob/master/presentation/xquery_shredding_a_table).

You'll want to look at that whole example, but the "filter" is based on a cross apply from the XML column like this:

{
--
-- get only the log entries having a data node in any position (//* syntax)
-------------------------------------------------
SELECT *
FROM   @entry AS [entry]
       CROSS APPLY [entry].[nodes]('/*') AS [table] ( [column] )
WHERE  CAST([table].[column].[query]('fn:local-name(.)') AS [SYSNAME]) = N'log'
       AND [entry].exist('//*[local-name()="data"]') = 1; 
}

Of course you'll want to use a value filter something like:

{
--
-- get only the log entries having a data node in any position (//* syntax)
-------------------------------------------------
SELECT [entry]
       , [entry].value(N'(./*/text())[1]', N'nvarchar(max)')              AS [value]
       , [entry].value(N'(./*/@application)[1]', N'sysname')              AS [application]
       , [entry].value(N'(./*/@timestamp)[1]', N'datetime')               AS [timestamp]
       , [entry].query(N'(./*/data/*)[1]')                                AS [data]
       , [entry].value(N'(./*/special_note/text())[1]', N'nvarchar(max)') AS [special_note]
FROM   @entry AS [entry]
       CROSS APPLY [entry].[nodes]('/*') AS [table] ( [column] )
WHERE  CAST([table].[column].[query]('fn:local-name(.)') AS [SYSNAME]) = N'log'
        AND [entry].value(N'(./*/text())[1]', N'nvarchar(max)')  = 'This is a log item.';
}

That should get you started.

Comments

0
SELECT * FROM mytable where mycolumn.value('/TxMsg/VehicleId[1]','nvarchar(max)') LIKE 'QWE123'

I hope Column 'mycolumn' is set as 'xml' data type in table 'mytable'. You need to use the 'value()' function to extract the data out of Xml. Hope this works.

Comments

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.