1

Say I have two JSON strings as follows:

[{"RowId":102787,"UserId":1,"Activity":"This is another test","Timestamp":"2017-11-25T14:37:30.3700000"}]

[{"RowId":102787,"UserId":2,"Activity":"Testing the Update function","Timestamp":"2017-11-25T14:37:30.3700000"}]

Both have the same properties but two of the properties in the second string have different values than the first (UserId and Activity). Is it possible, in Azure SQL Database T-SQL, to generate a third JSON string that contains the values in the second string that are different from the first? In other words, I'd like a string returned that looks like this:

[{"UserId":2,"Activity":"Testing the Update function"}]

Also, the solution should assume that the properties in the JSON strings are not known. I need this to be a generic solution for any two JSON strings.

1 Answer 1

3

Have not tried this on Azure, but it seems to work on SQL Server 2017 There is probably a more elegant way to get to the final JSON string other than through string manipulation, perhaps we can update the answer as better ways are found.

-- Expected : [{"UserId":2,"Activity":"Testing the Update function"}]
DECLARE  @jsonA     NVARCHAR(MAX) = '[{"RowId":102787,"UserId":1,"Activity":"This is another test","Timestamp":"2017-11-25T14:37:30.3700000"}]'
        ,@jsonB     NVARCHAR(MAX) = '[{"RowId":102787,"UserId":2,"Activity":"Testing the Update function","Timestamp":"2017-11-25T14:37:30.3700000"}]'
        ,@result    NVARCHAR(MAX) = ''

SELECT   @jsonA = REPLACE(REPLACE(@jsonA, ']', ''), '[', '')
        ,@jsonB = REPLACE(REPLACE(@jsonB, ']', ''), '[', '')

;WITH DSA AS
(
    SELECT *
    FROM OPENJSON(@jsonA)   
)
,DSB AS
(
    SELECT *
    FROM OPENJSON(@jsonB)   
)
SELECT @result  += CONCAT   (
                                 '"', B.[key], '":'
                                ,IIF(B.[type] = 2, B.[value], CONCAT('"', B.[value], '"'))  -- havent checked types other than 1 and 2; think there's a bool type?
                                ,','
                            )

FROM DSA    A
JOIN DSB    B ON A.[key] = B.[key]
WHERE A.[value] != B.[value]

SELECT CONCAT('[{', LEFT(@result, LEN(@result) - 1), '}]')
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. Very nice piece of work, and this works under Azure. I don't understand the nuances of JSON that well. What do you mean with your comment, "havent checked types other than 1 and 2; think there's a bool type?"
@RandyMinder; the types in JSON for numeric or string determine whether or not the value will be offered in quotes or not. I think that JSON, because of its root in javascript, may have a 3rd type: boolean. Just saying that I have not coded for any eventuality other than string and numeric. Hope that clears things up :)
Got it. I did a bit of research over the weekend, and a bit of tweeking of your code and got it working the way I need to. Thanks for your help.
@RandyMinder - good to hear! If there are any improvements that you have made that may benefit others - feel free to share.
@MarkD [{"RowId":102787,"UserId":1,"Activity":"This is another test","Timestamp":"2017-11-25T14:37:30.3700000","a":[{"b":"sssss"},{"b":"dfdfdf"}]}] how to compare this string using this SP

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.