简体   繁体   中英

Data transfer: JSON → SQL

😊

I would like to ask You for some help. In our production I would like to transfer many kind of data and I've decided to choose using of JSON for that. I've created the JSON string with all data on the side of the app and now I need to store it into my DB by using of stored procedure. Everything is good, but in some case I've met a little issue.

Request

I need to know how many defective pieces should be sent to some process (need to know: which process, what defect and how many...) 😉

Sorry for this confused description, but bellow is an example

Here is the part of JSON which I need to transform:
{"production":{"repairs":{"2":{"1":3},"4":{"3":5},"7":{"2":2,"4":4}}}}
Here is the required output:
RowID ProcessID ErrorID Amount
1 2 1 3
2 4 3 5
3 7 2 2
4 7 4 4
Test:

Here is some SQL script which makes exactly what I want, but I can't use it because it doesn't work in stored procedures...

DECLARE @json NVARCHAR(MAX) = '{"production":{"repairs":{"2":{"1":3},"4":{"3":5},"7":{"2":2,"4":4}}}}'

DECLARE @helper INT = 0
DECLARE @counter INT = 0

DECLARE @RepairData TABLE (RowID INT NOT NULL IDENTITY, ProcessID INT, ErrorID INT, Amount INT)

SELECT ROW_NUMBER() OVER(ORDER BY CAST("key" AS INT) ASC) AS 'Row', CAST("key" AS INT) AS 'ProcessID'
INTO #RepairProcesses
FROM OPENJSON(@json, '$.production.repairs')

WHILE @counter < (SELECT COUNT("key") FROM OPENJSON(@json, '$.production.repairs'))
BEGIN
    SET @counter = @counter + 1
    SET @helper = (SELECT ProcessID FROM #RepairProcesses WHERE Row = @counter)

    INSERT INTO @RepairData (ProcessID, ErrorID, Amount)
    SELECT @helper AS 'ProcessID', CAST("key" AS INT) AS 'ErrorID', CAST("value" AS INT) AS 'Amount'
    FROM OPENJSON(@json, '$.production.repairs."'+CAST(@helper AS NVARCHAR(3))+'"')
END

DROP TABLE #RepairProcesses

SELECT * FROM @RepairData
Output:
RowID|ProcessID|ErrorID|Amount|
-----+---------+-------+------+
    1|        2|      1|     3|
    2|        4|      3|     5|
    3|        7|      2|     2|
    4|        7|      4|     4|
Summary:

The reason why I can't use that is because I've used the WHILE loop and iteration for ProcessID in it and the stored procedures for some reason return syntax error in line where I'm using concatenation of the path string in the function OPENJSON . ( Even when it works in the classic "query mode" well... 🤨)

Error message (only within stored procedures):
SQL Error [102] [S0001]: Incorrect syntax near '+'.

The error occurs even when I don't use the concatenation and use the whole path string as the parameter... Seems like the function OPENJSON in stored procedures needs for the path string only absolute value in the ' '...

My request:

Guys I would like to ask You if somebody knows how to solve it in better way (maybe even without the WHILE loop?)...

Thanks a lot. 😉

I think you need this:

DECLARE @json NVARCHAR(MAX) = '{"production":{"repairs":{"2":{"1":3},"4":{"3":5},"7":{"2":2,"4":4}}}}'

SELECT
   RowId = ROW_NUMBER() OVER (ORDER BY CONVERT(int, j1.[key]), CONVERT(int, j2.[key])),
   ProcessID = j1.[key],    
   ErrorID = j2.[key],
   Amount = j2.[value]
FROM OPENJSON(@json, '$.production.repairs') j1
CROSS APPLY OPENJSON(j1.value) j2

Result:

RowId ProcessID ErrorID Amount
1 2 1 3
2 4 3 5
3 7 2 2
4 7 4 4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM