使用XML列中的值查询表

时间:2017-11-20 20:53:51

标签: sql sql-server xml xpath sql-server-2008-r2

我的表中有一个XML列,我想使用XML中的值来过滤表格中的行。

让表名为:mytable&让列名为:mycolumn

示例XML:

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

我应该如何查询我的表格,以便只能看到包含VehicleId = 'QWE123'的行?

我希望找到类似的解决方案:

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

3 个答案:

答案 0 :(得分:1)

您应该在where子句中使用exist()

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

如果您想使用变量或参数,请使用sql:variable

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

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

答案 1 :(得分:0)

在我的github存储库(https://github.com/KELightsey/chamomile/blob/master/presentation/xquery_shredding_a_table)中有一个完整的原型如何做到这一点。

您想要查看整个示例,但是&#34;过滤器&#34;基于XML列的交叉应用,如下所示:

{
--
-- 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; 
}

当然,您希望使用类似以下内容的值过滤器:

{
--
-- 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.';
}

这应该让你开始。

答案 2 :(得分:0)

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

我希望Column'mycolumn'在表'mytable'中设置为'xml'数据类型。您需要使用'value()'函数从Xml中提取数据。希望这有效。