2017-03-29 1 views
1

Ich möchte eine Funktion (MS SQL Server 2016), die sich selbst rekursiv aufrufen kann, um einen Baum zu durchlaufen und diesen Durchlauf als einen einzelnen Json-Wert zurückzugeben. Ich habe einen funktionierenden Codeabschnitt, der unten gezeigt wird, aber ich möchte etwas anderes tun als das klobige JSON_MODIFY, das ich benutzt habe. Leider kann ich keinen Weg finden, ohne es zu funktionieren. Wenn Sie die Codezeile mit JSON_MODIFY auskommentieren und die nächste Zeile auskommentieren, werden Sie sehen, was ich meine.MS SQL Server: Spalte als JSON behandeln

Gibt es eine bessere Lösung?

DROP TABLE dbo.Node; 
GO 

DROP FUNCTION dbo.NodeList; 
GO 

CREATE TABLE dbo.Node (
    NodeId INT NOT NULL , 
    ParentNodeId INT NULL , 
    NodeName NVARCHAR(MAX) 
); 
GO 

INSERT dbo.Node(NodeId, ParentNodeId, NodeName) 
VALUES (1, NULL, 'A'), (2, 1, 'B'), (3, 1, 'C'), (4, 3, 'D'), (5, 3, 'E'); 
GO 

CREATE FUNCTION dbo.NodeList(@ParentNodeId INT) RETURNS NVARCHAR(MAX) 
AS BEGIN 
    DECLARE @JsonOut NVARCHAR(MAX) = (
     SELECT n.NodeId , 
       n.NodeName , 
       JSON_MODIFY(dbo.NodeList(n.NodeId), '$.x', '') AS Children 
       -- dbo.NodeList(n.NodeId) AS Children 
     FROM dbo.Node n 
     WHERE ISNULL(n.ParentNodeId, -1) = ISNULL(@ParentNodeId, -1) 
     FOR JSON AUTO 
     ) ; 
    RETURN @JsonOut; 
END; 
GO 

PRINT dbo.NodeList(NULL); 
GO 

Die Ausgabe mit dem JSON_MODIFY ist genau das, was ich will ...

[{"NodeId":1,"NodeName":"A","Children":[{"NodeId":2,"NodeName":"B"}, 
{"NodeId":3,"NodeName":"C","Children":[{"NodeId":4,"NodeName":"D"}, 
{"NodeId":5,"NodeName":"E"}]}]}] 

... aber ohne sie, es geht alles schief ...

[{"NodeId":1,"NodeName":"A","Children":"[{\"NodeId\":2,\"NodeName\":\"B\"}, 
{\"NodeId\":3,\"NodeName\":\"C\",\"Children\":\" 
[{\\\"NodeId\\\":4,\\\"NodeName\\\":\\\"D\\\"}, 
{\\\"NodeId\\\":5,\\\"NodeName\\\":\\\"E\\\"}]\"}]"}] 

Danke Fortschritt für irgendwelche Ideen.

Antwort

0

Zwei Dinge:

1) Die JSON_MODIFY() erzeugt nicht wirklich genau das, was ich will. Mit dem ursprünglichen Code fügt JSON_MODIFY dem Wert ein Element mit dem Namen "x" und dem Wert "" hinzu.

2) Obwohl es keine perfekte Antwort ist, ist es viel sauberer, JSON_MODIFY() durch JSON_QUERY() (speziell mit JSON_QUERY (dbo.NodeList (...), '$') zu ersetzen. Es macht nicht nur mehr Sinn, auf diese Weise, aber es wird das zusätzliche "x" Artefakt los.

SQL offensichtlich wissen, dass, was von JSON_MODIFY kommt, ist nicht wirklich nur ein NVARCHAR (trotz seiner Unterschrift), aber ich kann kein anderes finden Möglichkeit, SQL zu denken, dass ein NVARCHAR JSON ist.