Friday, 22 August 2014

Parse JSON String by SQL script

The first question: Why do you need to parse JSON by SQL script? You can do it easily by C# or VB, or any PL.
But I sure that if you search this keyword and reach this post, you already have your own reason.
In my case, I got a task from Chris (my manager) in Microsoft, he want to migrate database, one of those step is parse about 100 k Json string and Insert into new table.
I have tried with C#, it worked, but I don't know how long, because I recognize that it is not a smart way and stop them ( program is running and thinking about C# solution). I try with SQL script.

Thanks 
And then try with script
Select * From
parseJSON
(
       '[{"Text":"YES","Value":"YES","Default":true},
       {"Text":"NO","Value":"NO","Default":false}]'

)

Great because we can get all field we need, but that is not the format we want. We should have table with three field TEXT, VALUE and Defaule.

That's why we need do more a little


  • Use this script to query table from JSON string
Select
       max(case when name='Text' then convert(Varchar(50),StringValue) else '' end) as [Text],
       max(case when name='Value' then convert(Varchar(50),StringValue) else '' end) as [Value],
       max(case when name='Default' then convert(bit,StringValue) else 0 end) as [Default]
From parseJSON
(
       '[{"Text":"YES","Value":"YES","Default":true},
       {"Text":"NO","Value":"NO","Default":false}]'
)
where ValueType = 'string' OR ValueType = 'boolean'
group by parent_ID


And this is result


All things I need are some where here, I hope you too.
If you have some problem with this Function, feel free to comment here.
Thanks

Reference: 
  1. https://www.simple-talk.com/sql/t-sql-programming/consuming-json-strings-in-sql-server/
  2. http://msdn.microsoft.com/en-us/library/ms187928.aspx
  3. http://www.w3schools.com/sql/func_convert.asp

50 comments:

  1. Nice and simple, thank you. Phil Factor did something great and you produced a useful simplified example for using it.

    ReplyDelete
  2. Hi, thanks for your example. But I wonder how to work for multi-level JSON, for example array?

    ReplyDelete
    Replies
    1. It can be solved with same this way, need more extending, but you should fix the number of level of JSON.
      I will think about this solution. Thanks for your idea

      Delete
    2. Just solved by joining the tables itself several times using 'WITH' function.

      Delete
    3. Can you please provide a sample code for multi-level json. I am strugling with it for quite a long time.

      Delete
    4. Please post the sample code for multi-level json.

      Delete
  3. Hay,mình cũng đang bế tắc ở việc parse Json blob thành data lưu vào table,chuỗi này khá dài và phức tạp. Anh có email hay thứ gì để liên lạc không?

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hi,
    When i am executing this parseJson function in sqlserver 2014, and then execute your select statement then error is coming . Error is"

    "Msg 245, Level 16, State 1, Line 1
    Conversion failed when converting the nvarchar value '1:@st' to data type int.."

    Please guide me what i can do, Quickly.

    ReplyDelete
    Replies
    1. Hi Behara,

      Can you send me your Json string?

      Thanks

      Delete
    2. Hi,

      select * from parseJSON(

      '[{"objectType":"Dashboard","id":"874ca359-05f2-4bb9-8f68-eb792ebbf24e"},
      {"objectType":"Dashboard","id":"15deb54a-71ba-4077-92a2-db55041799e7"},
      {"objectType":"Dashboard","id":"1496c0b9-071f-4a06-bd2b-aa80d127428a"}]')


      Delete
    3. Plz send me verified parseJSON() function

      Delete
    4. I am using sqlserver 2014 Environment

      Delete
    5. element_id sequenceNo parent_ID Object_ID NAME StringValue ValueType
      1 0 1 NULL objectType Dashboard string
      2 0 1 NULL id 874ca359-05f2-4bb9-8f68-eb792ebbf24e string
      3 0 2 NULL objectType Dashboard string
      4 0 2 NULL id 15deb54a-71ba-4077-92a2-db55041799e7 string
      5 0 3 NULL objectType Dashboard string
      6 0 3 NULL id 1496c0b9-071f-4a06-bd2b-aa80d127428a string
      7 1 4 1 NULL 1 object
      8 2 4 2 NULL 2 object
      9 3 4 3 NULL 3 object
      10 1 NULL 4 - array

      Delete
    6. This comment has been removed by the author.

      Delete
    7. The Above Json with ParseJson working fine for me.

      Delete
    8. this code looks great, but it's quite buggy, and no attention was made to case. SQL 2016 now supports native Json

      Delete
    9. Hi,
      I have the same issue.
      Function is running fine on SQL SERVER 2005 but fails on 2012
      Running:
      select * from [dbo].[parseJSON] ('{"PhoneNumber":"11111111","Description":"BlueD"}')
      Output:
      Msg 245, Level 16, State 1, Line 6
      Conversion failed when converting the nvarchar value '1:@st' to data type int.

      I hope someone can help with this.
      Thanks!
      nathan.maoz@gmail.com

      Delete
    10. This comment has been removed by the author.

      Delete
  6. can you please tell how to parse return value of
    https://maps.googleapis.com/maps/api/distancematrix/json?origins=28.6585734,77.3609195&destinations=28.624214,77.434532&language=en-EN

    Your parseJSON() function is not able to put the Hierarchy table properly.
    Thanks in advance

    ReplyDelete
    Replies
    1. {
      "destination_addresses" : [ "Dundahera, Ghaziabad, Uttar Pradesh, India" ],
      "origin_addresses" : [
      "373, Block B, Sector 14, Vasundhara, Ghaziabad, Uttar Pradesh 201012, India"
      ],
      "rows" : [
      {
      "elements" : [
      {
      "distance" : {
      "text" : "13.6 km",
      "value" : 13579
      },
      "duration" : {
      "text" : "32 mins",
      "value" : 1900
      },
      "status" : "OK"
      }
      ]
      }
      ],
      "status" : "OK"
      }

      Remove the spaces before the : and check

      Delete
  7. Select
    max(case when name='AccountCode' then convert(Varchar(50),StringValue) else '' end) as [AccountCode],
    max(case when name='Reportablename' then convert(Varchar(50),StringValue) else '' end) as [AccountReportableName]
    From dbo.parseJSON (
    '[{"Reportablename": "Not Available", "AccountCode": "0010377"},
    {"Reportablename": "Not Available", "AccountCode": "0010377"}]')
    where name='AccountCode' OR name='Reportablename'
    group by parent_ID


    Executing above query, returns below result. Id does not return actual values.

    AccountCode AccountReportableName
    ------------------------------
    @string4 @string2
    @string8 @string6

    ReplyDelete
    Replies
    1. For me

      AccountCode AccountReportableName
      0010377 Not Available
      0010377 Not Available

      Delete
    2. For me

      AccountCode AccountReportableName
      0010377 Not Available
      0010377 Not Available

      Delete
  8. how to use this code in db2.

    ReplyDelete
  9. hi ,
    is it possible to do it in ibm data studio ?
    if yes then how ??

    ReplyDelete
    Replies
    1. I think it maybe not. This is solution for simple Json, I expect Json string with 1 level deep

      Delete
  10. This one handles complex json

    http://www.codeproject.com/Articles/1000953/JSON-for-Sql-Server-Part

    ReplyDelete
  11. how to parse JSON file in sql server using the parseJSON() function?

    ReplyDelete
  12. Hi, This function works for me however it took 6-7 sec to convert JSON file to table values. Is there any way to improve the performance of this function.

    ReplyDelete
  13. Cant fine the query any more, could you post the function again?

    ReplyDelete
  14. This is just awesome . i have been looking for last 2days. finally this works. can you guide me how can i achieve for multiple json at time ?
    Thanks

    ReplyDelete
  15. Hi,
    I have the following issue:
    Function is running OK on SQL SERVER 2005 but FAILS on SQL SERVER 2012
    Running:
    select * from [dbo].[parseJSON] ('{"PhoneNumber":"11111111","Description":"BlueD"}')
    Output:
    Msg 245, Level 16, State 1, Line 6
    Conversion failed when converting the nvarchar value '1:@st' to data type int.

    I hope someone can help with this.
    Thanks!
    nathan.maoz@gmail.com

    ReplyDelete
    Replies
    1. I have the same problem - did you ever get this to work?

      Thanks!
      Todd

      Delete
    2. I am getting the same error as well. This was working fine until the database was changed to have a collation setting of 'SQL_Latin1_General_CP850_BIN. This collation setting is much more case sensitive and I had many case errors in the function itself. Once I fixed those and I was able to compile it, I still get the same error as above. Conversion failed...

      Delete
  16. Hi,
    I took the json from table and used parseJson function then inserted into a table.
    My next aim is to add an extra entry into newly created table and need to make it as json.

    Is it possible ?

    ReplyDelete
  17. Its really very useful stuff for me.. thanks dude

    ReplyDelete
  18. @Todd Gilson .. its working in my machine 2018 sql server

    ReplyDelete
  19. FANTASTIC!!! Thank you, working on 2012. I do get an invalid len passed for the string, due to some data being trimmed on the database making badly formed json, which I cant get updated. I have to filter them out unfortunately in the query. I dont want to touch the function code. Top work

    ReplyDelete
  20. Msg 245, Level 16, State 1, Line 9
    Conversion failed when converting the nvarchar value ' EmployeeRef' to data type int.

    select * from
    parsejson(
    '[{EmployeeRef:23ece5d871ee45f18bc89cf434cef055,Name:Kim Evans,Primary:True,Role:BusinessManager},
    {EmployeeRef:53aa31d3a27948ac9ca7e68d29ee23c3,Name:Gary Evans,Primary:True,Role:SalesManager},
    {EmployeeRef:6a20712f0a7a49d3a968ed30903c40f9,Name:Claire Watson,Primary:True,Role:SalesRep}]')

    ReplyDelete
  21. this doesn't work with unicode (Vietamese), how to fix that, thanks so much.

    ReplyDelete
  22. Hello, I get this result from the Parse JSON function:

    1 0 1 NULL EmployeeId 117800 real
    2 0 1 NULL EmployeeNumber @string3 real
    3 0 1 NULL EmployeeSurname @string5 real
    4 0 1 NULL EmployeeFirstname @string7 real
    5 0 1 NULL EmployeeMidname @string9 real
    6 0 1 NULL Gender @string11 real
    7 0 1 NULL Grade @string13 real
    8 0 1 NULL CurrentLocation @string15 real
    9 0 1 NULL CurrentLocationCode @string17 real
    10 0 1 NULL SavingsAccountNo @string19 real
    11 0 1 NULL CurrentAccountNo @string21 real
    12 1 2 1 NULL 1 object
    13 1 NULL 2 - array

    The column values shows @string3, @string5, @string7, etc... It does not return the actual Values. What may be wrong?

    ReplyDelete
  23. Hello. would this also be able to convert the string value to numeric and datetime? if it doesn't how can i make it do it? thanks in advance

    ReplyDelete
  24. Hi,Is this thread still active?

    ReplyDelete
  25. {

    "Id": 23423,
    "fname": A,
    "lname": "K"

    }

    The function is not recognising value in double quotes in source file.

    When I print it it does get the corresponding key but not the value instead it fetches @string8 real.


    Could you please help fetch the values in double quptes?

    ReplyDelete
    Replies
    1. @Roccky_Ak

      I had the same problem - deleting the empty space after the colon helped me.
      Try:
      {

      "Id": 23423,
      "fname": A,
      "lname": "K"

      }

      {

      "Id":23423,
      "fname":A,
      "lname":"K"
      }

      Delete
  26. Thank You and I have a nifty offer: Whole House Renovation Checklist Pdf home renovation jobs

    ReplyDelete