【问题标题】:Query table using values in XML column使用 XML 列中的值查询表
【发布时间】:2017-11-20 20:53:51
【问题描述】:

我的表中有一个 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'

【问题讨论】:

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


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

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

      您会想查看整个示例,但“过滤器”是基于 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.';
      }
      

      这应该让你开始。

      【讨论】:

        【解决方案3】:
        SELECT * FROM mytable where mycolumn.value('/TxMsg/VehicleId[1]','nvarchar(max)') LIKE 'QWE123'
        

        我希望在表“mytable”中将列“mycolumn”设置为“xml”数据类型。您需要使用“value()”函数从 Xml 中提取数据。希望这行得通。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-31
          • 2020-12-07
          • 1970-01-01
          • 2017-07-01
          • 2018-07-06
          • 2020-08-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多