【发布时间】:2017-09-24 14:44:10
【问题描述】:
我正在寻找使用动态 SQL 查询直接从 (T)SQL 创建嵌套 JSON 字符串的最佳解决方案。
在 SQL Server 2016 中,使用如下语句创建平面 JSON 字符串很容易:
SELECT *
FROM tblTableName
FOR JSON AUTO
如果您需要更复杂的嵌套结果,您可以使用简单的递归例程,例如:
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是tblTableName中每条记录的ID
IDParent 是 tblTableName 中记录的父 ID
此递归函数仅在 SQL-Query 固定时才有效。
在我的情况下,我有很多嵌套结构的查询。为了支持所有许多嵌套 SQL 查询,我尝试修改上面的 NestedJSON 函数,但接缝是不允许在函数中使用动态 SQL。我尝试了以下选项:
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;
但是所有的修改都导致了同样的错误:“只有函数和一些扩展的存储过程可以在一个函数中执行。”
我从 vb.net 调用 SQL 服务器,因此我可以创建一个附加函数来树化嵌套的 JSON,但这是我的最后一个选择。我认为最快最干净的解决方案是在 (T)SQL 中进行完整的嵌套。
那么,有没有人可以帮助我创建一个能够支持动态的解决方案 SQL 并返回一个嵌套的 JSON?
感谢任何帮助。
阿诺
【问题讨论】:
-
可以使用存储过程代替函数
-
感谢您的建议。我还没有想到远程过程。远程过程和函数一样快吗?
-
如果你的 sp 做同样的事情,它将有同样的执行时间。不同的是你如何接收结果:funcion结果可以直接在查询中使用,sp结果需要保存后才能使用
标签: sql-server json vb.net nested dynamic-sql