简体   繁体   English

MS SQL Server:将列视为Json

[英]MS SQL Server: Treat Column As Json

I want a function (MS SQL Server 2016) that can recursively call itself to traverse a tree and to return that traversal as a single Json value. 我想要一个函数(MS SQL Server 2016),它可以递归地调用自身来遍历树并将该遍历作为单个Json值返回。 I have a working chunk of code, shown below, but I'd like to do something other than the clunky JSON_MODIFY I've used. 我有一大堆代码,如下所示,但我想做的事情不仅仅是我用过的笨重的JSON_MODIFY。 Unfortunately, I can't find a way to make it work without it. 不幸的是,没有它,我找不到让它工作的方法。 If you comment out the line of code with the JSON_MODIFY and uncomment the next line, you'll see what I mean. 如果您使用JSON_MODIFY注释掉代码行并取消注释下一行,您将看到我的意思。

Is there a better solution? 有更好的解决方案吗?

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

The output with the JSON_MODIFY is exactly what I want... JSON_MODIFY的输出正是我想要的......

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

... but without it, it all goes wrong ... ......但没有它,一切都会出错......

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

Thanks in advance for any ideas. 提前感谢任何想法。

Two things: 两件事情:

1) The JSON_MODIFY() doesn't actually generate exactly what I want. 1)JSON_MODIFY()实际上并不能完全生成我想要的内容。 Using the original code, the JSON_MODIFY adds an element with the name 'x' and the value '' to the value. 使用原始代码,JSON_MODIFY将值添加名为“x”且值为“”的元素。

2) Although not a perfect answer, it is much cleaner to replace JSON_MODIFY() with JSON_QUERY() (specifically with JSON_QUERY(dbo.NodeList(...), '$'). Not only does it make more sense, this way but it gets rid of the extra 'x' artifact. 2)虽然不是一个完美的答案,但用JSON_QUERY()(特别是JSON_QUERY(dbo.NodeList(...),'$')替换JSON_MODIFY()会更清晰。不仅这样更有意义,这种方式但它摆脱了额外的'x'神器。

SQL obviously know that whatever comes back from JSON_MODIFY isn't really just an NVARCHAR (despite its signature), but I can't find any other way to make SQL think that an NVARCHAR is JSON. SQL显然知道从JSON_MODIFY返回的内容并不仅仅是一个NVARCHAR(尽管它的签名),但我找不到任何其他方法让SQL认为NVARCHAR是JSON。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM