在CASE语句中将JSON_MODIFY与JSON_QUERY一起使用时出现问题

时间:2018-07-11 22:13:06

标签: sql json sql-server

这是问题。我的数据库中有一列(类型为nvarchar(max)),用于存储JSON。我在该列中存储了纯字符串或对象,如下所示:

     JsonTable
|--|-------------------|
|Id|JsonValue          |
|--|-------------------|
|0 |{"sample":"object"}|
|--|-------------------|
|1 |"plain-string"     |
|--|-------------------|

我正在尝试使用JSON_MODIFY将这些值与另一个表的值合并。

以下内容仅适用于对象,不适用于字符串:

SELECT JSON_MODIFY('{}',  '$.Values', JSON_QUERY(JsonValue))
FROM JsonTable
WHERE Id = 0 -- Fails when string is included in results

-- Result = |------------------------------|
            |{"Values":{"sample":"object"} |
            |------------------------------|

但是它无法解析普通字符串(可以理解,因为它不是JSON) 因此,我的解决方案是添加一个case语句来处理字符串。但是,这不起作用,因为将其包装在CASE语句字符串中会逸出JSON_QUERY对象并在最终的JSON_MODIFY结果中将其弄乱。

以下内容无法正常工作:

SELECT JSON_MODIFY('{}',  '$.Values',
    CASE
      WHEN ISJSON(JsonValue) > 0 THEN JSON_QUERY(JsonValue)
      ELSE REPLACE(JsonValue, '"','')
    END)
FROM JsonTable

-- Result = |-------------------------------------|
            |{"Values":"{\"sample\"::\"object\"}" |
            |-------------------------------------|
            |{"Values":"plain-string"             |
            |-------------------------------------|

2 个答案:

答案 0 :(得分:0)

所以我无法弄清楚为什么在CASE语句中包装JSON_QUERY不能正确返回,但是我开始使用这种解决方法,该方法有些冗长和混乱,但效果很好:

SELECT
    CASE
      WHEN ISJSON(JsonValue) > 0
      THEN
        (SELECT JSON_MODIFY('{}',  '$.Values', JSON_QUERY(JsonValue)))
      ELSE
        (SELECT JSON_MODIFY('{}',  '$.Values', REPLACE(JsonValue, '"','')))
    END
FROM JsonTable

-- Result = |-------------------------------------|
            |{"Values":{"sample":"object"}        |
            |-------------------------------------|
            |{"Values":"plain-string"             |
            |-------------------------------------|

答案 1 :(得分:-1)

您是否尝试过使用string_escape函数来格式化JSON字符串;即假设您的问题与正确转义引号有关? http://sqlfiddle.com/#!18/9eecb/24391

SELECT JSON_MODIFY('{}',  '$.Values', 
  case 
    when ISJSON(JsonValue) = 1 then JSON_QUERY(JsonValue)
    else STRING_ESCAPE(JsonValue,'json')
  end
)
FROM (
  values
   (0, '{"sample":"object"}')
  ,(1, 'plain-string')
  ,(2, '"plain-string2"')
) JsonTable(Id,JsonValue)

STRING_ESCAPE documentation