2

Here's the issue. I have a column in my database (type nvarchar(max)) that I am storing JSON in. I am storing both plain strings or objects in that column like the following:

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

I am trying to use JSON_MODIFY to merge these values with another table's values.

The following works fine for just objects, but not strings:

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

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

However it fails to parse the ordinary string (understandably since it is not JSON) So then my solution was to add a case statement to handle strings. However this does not work as wrapping it in a CASE statement string escapes the JSON_QUERY object and garbles it up in the final JSON_MODIFY result.

The following does not work as expected:

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 Answers 2

2

So I was unable to figure out really why wrapping JSON_QUERY in a CASE statement doesnt return properly, but instead I started using this workaround which is a bit verbose and messy but it works perfectly fine:

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"             |
            |-------------------------------------|
Sign up to request clarification or add additional context in comments.

Comments

-1

Have you tried using the string_escape function to format your string for JSON; i.e. assuming your issue is related to the correctly escaping the quotes? 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

1 Comment

That does the opposite of what I need, that adds even more escape characters, I'm trying to have none. Querying that string entry with string_escape would give me {"Values":"\\\"plain-string\\\""}. Additionally the string isnt the issue, its the object.

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.