Query json dictionary data in SQL
Use JSON_TABLE
and then UNPIVOT
if you want the values in rows instead of columns:
SELECT *
FROM (
SELECT p.*
FROM table_name t
CROSS JOIN
JSON_TABLE(
t.value,
'$'
COLUMNS (
a PATH '$.a',
b PATH '$.b',
c PATH '$.c'
)
) p
)
UNPIVOT ( value FOR key IN ( a, b, c ) );
So for some sample data:
CREATE TABLE table_name (
value CLOB CONSTRAINT ensure_json CHECK (value IS JSON)
);
INSERT INTO table_name ( value ) VALUES ( '{"a":"value1", "b":"value2", "c":"value3"}' );
This outputs:
KEY | VALUE
:-- | :-----
A | value1
B | value2
C | value3
db<>fiddle here
If you want to do it dynamically then you can parse the JSON in PL/SQL and use GET_KEYS
to get a collection of key names and then access the correct one by its position and correlate that to the value using FOR ORDINALITY
:
CREATE FUNCTION get_key(
pos IN PLS_INTEGER,
json IN CLOB
) RETURN VARCHAR2
AS
doc_keys JSON_KEY_LIST;
BEGIN
doc_keys := JSON_OBJECT_T.PARSE ( json ).GET_KEYS;
RETURN doc_keys( pos );
END get_key;
/
Then:
SELECT get_key( j.pos, t.value ) AS key,
j.value
FROM table_name t
CROSS APPLY JSON_TABLE(
t.value,
'$.*'
COLUMNS (
pos FOR ORDINALITY,
value PATH '$'
)
) j;
Outputs:
KEY | VALUE
:-- | :-----
a | value1
b | value2
c | value3
db<>fiddle here
Output json in dictionary (string-indexed list) notation from SQL Server
I don't think that you can generate JSON output with variable key names using FOR JSON AUTO
or FOR JSON PATH
, but if you can upgrade to SQL Server 2017, the following approach, that uses only JSON built-in support, is a possible option:
Table:
CREATE TABLE Data (
Id varchar(2),
Customer varchar(50),
Product varchar(50),
[Date] date,
[Count] int
)
INSERT INTO Data
(Id, Customer, Product, [Date], [Count])
VALUES
('A1', 'Walmart', 'Widget', '20200101', 5),
('B2', 'Amazon', 'Thingy', '20200102', 10),
('C3', 'Target', 'Gadget', '20200201', 7)
Statement:
DECLARE @json nvarchar(max) = N'{}'
SELECT @json = JSON_MODIFY(
@json,
CONCAT(N'$."', ID, N'"'),
JSON_QUERY((SELECT Customer, Product, [Date], [Count] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER))
)
FROM Data
SELECT @json
Result:
{"A1":{"Customer":"Walmart","Product":"Widget","Date":"2020-01-01","Count":5},"B2":{"Customer":"Amazon","Product":"Thingy","Date":"2020-01-02","Count":10},"C3":{"Customer":"Target","Product":"Gadget","Date":"2020-02-01","Count":7}}
Notes:
Using a variable or expression instead of value for path
parameter in JSON_MODIFY()
is available in SQL Server 2017+. JSON_QUERY()
is used to prevent the escaping of the special characters.
Insert a dictionary into SQL database created using JSON in Python
To insert the json into your database, don't convert it to a Python object; just store the string as read from the file.
with open(peripheralsJsonFile).read() as f:
peripheralsInfo = f.read()
myquery = """INSERT INTO hw_info(hostname, peripheralsInfo) VALUES(%s,%s)"""
cursor.execute(myquery, (hostname, peripheralsInfo))
When you want to use the data in your program later on you would pass the string from the SELECT query through json.loads()
to make it a Python object.
EDIT
Two remarks here.
prefipheralsInfo = open(peripheralsJsonFile).read()
does not close the file properly after reading, hence I used a context manager that takes care of that behind the scenes.You format your query string by using Python's string interpolation. That makes your program vulnerable to SQL injection attacks. In my example I make use of a parameterized query to circumvent that vulnerability. Parameters also help making sure that your input is passed to your DB as the correct datatype.
Related Topics
Sqlite Database - Select the Data Between Two Dates
Querying Active Directory from SQL Server 2005
How to Detect If a String Contains Special Characters
Curious Issue with Oracle Union and Order By
SQL Server Variable Scope in a Stored Procedure
Entity Framework Skip/Take Is Very Slow When Number to Skip Is Big
Connecting to Oracle Database Using SQL Server Integration Services
Sql: Aggregating Strings Together
Capturing Multiple Error Messages from a Single Statement Inside Try Catch
Store and Reuse Value Returned by Insert ... Returning
Concat Function Is Not Working - Invalid Number of Arguments
Sp_Msforeachdb: Only Include Results from Databases with Results
Rotate/Pivot Table with Aggregation in Oracle
Why Is 30 the Default Length for Varchar When Using Cast
Conversion Failed When Converting the Nvarchar Value ... to Data Type Int