I'm looking for the best solution to create a nested JSON-string directly from (T)SQL with a dynamic SQL query.
In SQL Server 2016, it is easy to create a flat JSON string with a statement like this:
SELECT *
FROM tblTableName
FOR JSON AUTO
If you need a more complex nested result you can use a simple recursive routine like:
CREATE FUNCTION [dbo].[NestedJSON](@Id uniqueidentifier)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @Json NVARCHAR(MAX) = '{}';
IF @Id Is NULL
SET @Json =
(SELECT *, JSON_QUERY(dbo.NestedJSON(Id) ) AS child
FROM dbo.tblTableName
WHERE IDParent is NULL
FOR JSON AUTO);
ELSE
SET @Json =
(SELECT *, JSON_QUERY(dbo.NestedJSON(Id) ) AS child
FROM dbo.tblTableName
WHERE IDParent = @Id
FOR JSON AUTO);
RETURN @Json
END
Id is the ID of each record in tblTableName
IDParent is the parent Id of the record in tblTableName
This recursive function only works if the SQL-Query is fixed.
In my situation I have many queries with a nested stucture. To support all the many nested SQL-queries I tried to modify the above NestedJSON function, but is seams that it is not allowed to use dynamic SQL in a function. I tried options like:
IF @Id Is NULL
Set @SQL = 'SELECT @Json=(SELECT ' + @FieldList + ' ,JSON_QUERY(dbo.MenuNested(' + @Id + ') ) AS Child FROM ' + @TheTables + ' WHERE IDParent is NULL FOR JSON AUTO)'
ELSE
Set @SQL = 'SELECT @Json=(SELECT ' + @FieldList + ' ,JSON_QUERY(dbo.MenuNested(' + @Id + ') ) AS Child FROM ' + @TheTables + ' WHERE IDParent = ' + @Id + ' FOR JSON AUTO)'
Exec(@SQL)
--or
execute sp_executesql @SQL;
But all modifications resulted in the same error: "Only functions and some extended stored procedures can be executed from within a function."
I call the SQL server from vb.net so I could create an additional function to tree-a-fy the nested JSON, but this is the last option for me. I think the fasted and cleanest solution is to do the complete nesting in (T)SQL.
So, Is there anyone who can help me to create a solution able to support Dynamic SQL and return a nested JSON?
Thanks any help is appreciated.
Arno