Je recherche la meilleure solution pour créer une chaîne JSON imbriquée directement à partir de (T) SQL avec une requête SQL dynamique.JSON imbriqué avec requête dynamique
Dans SQL Server 2016, il est facile de créer une chaîne JSON plat avec une déclaration comme celle-ci:
SELECT *
FROM tblTableName
FOR JSON AUTO
Si vous avez besoin d'un résultat imbriqué plus complexe, vous pouvez utiliser un simple routine récursive comme:
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
Cette fonction récursive ne fonctionne que si la requête SQL est fixe.
Dans ma situation, j'ai beaucoup de requêtes avec une structure imbriquée. Pour prendre en charge toutes les nombreuses requêtes SQL imbriquées, j'ai essayé de modifier la fonction NestedJSON ci-dessus, mais il est évident qu'il n'est pas permis d'utiliser le SQL dynamique dans une fonction. J'ai essayé des options comme:
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;
Mais toutes les modifications ont abouti à la même erreur: « Seules les fonctions et des procédures stockées étendues peuvent être exécutées à l'intérieur d'une fonction. »
J'appelle le serveur SQL à partir de vb.net afin que je puisse créer une fonction supplémentaire pour arborer le JSON imbriqué, mais c'est la dernière option pour moi. Je pense que la solution la plus rapide et la plus propre est de faire l'imbrication complète en (T) SQL.
Alors, y a-t-il quelqu'un qui peut m'aider à créer une solution capable de prendre en charge le langage dynamique SQL et de renvoyer un fichier JSON imbriqué?
Merci toute aide est appréciée.
Arno
Vous pouvez utiliser la procédure stockée au lieu de la fonction – sepupic
Merci pour le conseil. Je ne pensais pas encore à une proc distante. Une procédure à distance est-elle aussi rapide qu'une fonction? – Arno
Si votre sp fait les mêmes choses, il aura le même temps d'exécution. La différence est la façon dont vous recevez le résultat: le résultat de funcion peut être utilisé directement dans les requêtes, le résultat sp doit être sauvegardé avant de pouvoir l'utiliser – sepupic