I’m having trouble to getting JSON to work in SIngleStore DB. I’m using MSSQL for my project and I’m trying to translate it to SingleStore.
Consider this table:
CREATE TABLE dbo.Categories (
id int NOT NULL,
parentId int NULL,
active bit NOT NULL,
name nvarchar(32) NOT NULL
);
It’s an hierarchical categories table (so 1 - Cars can have as child: 11 - Used, 12 - New, for example).
Using this T-SQL query:
SELECT pc.id, pc.name,
(
SELECT sc.id, sc.name
FROM Categories AS sc
WHERE sc.parentId = pc.id AND sc.active = 1
ORDER BY name
FOR JSON PATH
) AS categories
FROM Categories AS pc
WHERE pc.parentId IS NULL AND pc.active = 1
ORDER BY id
FOR JSON PATH
I get this result in one TEXT column:
[
{"id": 1, "name": "Cars", "categories": [
{"id": 11, "name": "Used"},
{"id": 12, "name": "New"}
]}
]
NOTICE that is an hierarchical JSON generated from multiple tables (one in this case, but I can nest as many SELECT
statements as sub-queries, as long they are FOR JSON PATH
or FOR JSON AUTO
). The TO_SQL(*)
seems to work only with a single set of rows from one and only one table =\
So I can get a full database graph converted to a single JSON without too much trouble.
How can I do the same in SingleStore?
For reading JSON, I use this:
INSERT INTO Categories(id, name)
(
SELECT OPENJSON(@JSON) WITH (
'id' VARCHAR(32) '$.id',
'name' NVARCHAR(128) '$.name'
'parentId' VARCHAR(32) '$.parentId'
)
WHERE parentId IS NULL
)
When using arrays, I can use CROSS APPLY
to mix JSON, for example:
SELECT SalesOrderID, OrderDate, value AS Reason
FROM Sales.SalesOrderHeader
CROSS APPLY OPENJSON (SalesReasons) WITH (value NVARCHAR(100) '$')
So I can use a JSON as a table (meaning: I’m able to JOIN it, select from it, filter from it, etc.).
Most of the times, my stored procedures read data from a JSON argument:
CREATE PROCEDURE FooBar(@JSON NVARCHAR(MAX)) AS BEGIN
DECLARE @valueA VARCHAR(32);
DECLARE @valueB INT;
DECLARE @valueC DATETIMEOFFSET(2);
SELECT @valueA = string, @valueB = integer, @valueC = iso_date FROM
OPENJSON(@JSON) WITH (
string VARCHAR(32) '$.string',
integer INT '$.integer',
iso_date DATETIMEOFFSET(2) '$.iso_date'
);
SELECT @valueA, @valueB, @valueC;
END
If I execute this proc:
EXEC FooBar @JSON = '{"string": "Teste", "integer": 42, "iso_date": "2021-01-04T21:32:00Z"}';
I get this:
+-------+----+----------------------------------+
| Teste | 42 | January 4, 2021, 09:32:00 PM GMT |
+-------+----+----------------------------------+
How can I do such JSON read/write with SingleStore?