【问题标题】:Return value for XML column without XML tags没有 XML 标记的 XML 列的返回值
【发布时间】:2019-10-30 04:48:41
【问题描述】:

我试图在 SQL Server 2016 中不使用 convert 或 cast 来查找 XML 列中特定字段的值,但是 XML 不包含传统标记。我对 XML 数据不太熟悉,所以我试图了解如何最好地完成这一点。

我尝试过使用[column].value,但是我无法返回结果,因为我不知道如何识别没有标签的节点。

这是我正在运行的查询:

select customeridentifier, customerdemographics 
from customerdatafile

customerdemographics 列是 xml,如下所示:

{  
  "request": {  
    "customer_id": "12345efg"
    "ip_address": "12.1.4.12"
    "name.value": "JAMES"
  },
  "customer_compatibility": 40
}

我希望返回“customer_compatibility”的值,我试图通过以下方式完成:

customerdemographics.value('(customer_compatibility)[1]','nvarchar(max)') 

返回一个空值。另一方面,

customerdemographics.value('(.)','nvarchar(max)') 

毫无问题地返回 XML 字段的完整值。

从 XML 列返回 customer_compatibility 值的最有效方法是什么?最坏的情况,我可以进行转换/转换,但由于数据大小,查询会很慢。

【问题讨论】:

  • 那是 不是 XML - 那是 JSON :.....

标签: json sql-server xml


【解决方案1】:

customerdemographics 列中的数据似乎是JSON 格式(尽管key: value 对之间缺少,)。 SQL Server 2016 支持JSON,您可以尝试使用JSON_VALUE()(从JSON 字符串中提取标量值)和OPENJSON()(解析JSON 字符串的表值函数)解析此JSON并将对象和属性作为行和列返回)。

表:

CREATE TABLE customerdatafile (
   customeridentifier int,
   customerdemographics nvarchar(max)
)
INSERT INTO customerdatafile 
   (customeridentifier, customerdemographics)
VALUES
   (1, N'{"request": {"customer_id": "12345efg", "ip_address": "12.1.4.12", "name.value": "JAMES"}, "customer_compatibility": 40}')

提取单个值:

SELECT 
   customeridentifier, 
   JSON_VALUE(customerdemographics, '$.customer_compatibility') AS customer_compatibility
FROM customerdatafile    

解析整个 JSON:

SELECT d.customeridentifier, j.*
FROM customerdatafile d
CROSS APPLY OPENJSON(d.customerdemographics) WITH (
   customer_id nvarchar(100) '$.request.customer_id',
   ip_address nvarchar(100) '$.request.ip_address',
   [name.value] nvarchar(100) '$.request."name.value"',
   customer_compatibility int '$.customer_compatibility'
) j

结果:

customeridentifier  customer_compatibility
1                   40

customeridentifier  customer_id ip_address  name.value  customer_compatibility
1                   12345efg    12.1.4.12   JAMES       40

【讨论】:

    【解决方案2】:

    您似乎正试图以root 节点的身份访问customer_compatibility。尝试将您的json 转换为xml 并修改您的xpath,似乎工作正常。

    declare @strJson xml = '<test><root>
       <customer_compatibility>40</customer_compatibility>
       <request>
          <customer_id>12345efg</customer_id>
          <ip_address>12.1.4.12</ip_address>
          <name.value>JAMES</name.value>
       </request>
    </root></test>'
    
    
    select @strJson.value('(//customer_compatibility)[1]','nvarchar(max)') 
    

    【讨论】:

      【解决方案3】:

      如果你真的有 JSON

      declare @j varchar(1000);
      
      set @j = '{  
        "request": {  
          "customer_id": "12345efg",
          "ip_address": "12.1.4.12",
          "name.value": "JAMES"
        },
        "customer_compatibility": 40
      }';
      
      print JSON_VALUE(@j, '$.request.customer_id');
      
      select * from openjson(@j);
      select * from openjson(JSON_QUERY(@j, '$.request'));
      

      请注意,我在您的字符串中添加了逗号

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-18
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        • 1970-01-01
        相关资源
        最近更新 更多