【问题标题】:How to create JSON from variables in SQL SERVER using FOR JSON AUTO如何使用 FOR JSON AUTO 从 SQL SERVER 中的变量创建 JSON
【发布时间】:2021-12-07 22:17:49
【问题描述】:

我正在尝试在 SQL Server 2016 中编写查询,其中我:

  1. 遍历一系列行
  2. 将结果读入变量
  3. 从这些变量创建 JSON 对象以存储在我的数据库中

这是我目前拥有的代码的基本示例


DECLARE 
    @test1 int,
    @test2 varchar(255)
DECLARE db_update_cursor CURSOR FOR
    SELECT test1, test2
    FROM sourceTable
OPEN db_update_cursor 
FETCH NEXT FROM db_update_cursor INTO @test1, @test2
WHILE @@FETCH_STATUS = 0  
    BEGIN 
    INSERT INTO destinationTable(testRow)
    VALUES (SELECT @test1, @test2 FOR JSON AUTO)
FETCH NEXT FROM db_update_cursor INTO @test1, @test2
END

CLOSE db_update_cursor  
DEALLOCATE db_update_cursor

由此,我希望得到一个看起来像这样的 Json 对象:

[
  {
    "test1": 5,
    "test2": "something"
  }
]

当我尝试运行此程序时,我收到错误消息:“FOR JSON AUTO 需要至少一个表来生成 JSON 对象。使用 FOR JSON PATH 或添加带有表名的 FROM 子句。”

实施此工作流程的最佳方式是什么?

【问题讨论】:

  • 您发布的 SQL 甚至无法编译。请发布测试表的整个架构。看起来您的示例可能不是 100% 1-1 的真实代码。我的猜测是您正在尝试更新 testtable,将 testRow 设置为同一行中其他字段的 json?
  • 抱歉,这应该是两个不同的表,我已经更新了帖子以反映这一点
  • 我认为,添加示例数据是合适的。

标签: sql json sql-server


【解决方案1】:

SQL Server 无法使用FOR JSON AUTO 生成 JSON,除非它具有用于构建对象的架构。 INSERT 语句中的 SELECT 只是在尝试生成 JSON 时选择了几个变量值。在游标的范围内,SQL Server 没有任何用于生成 JSON 对象的上下文。

您不需要光标。看看这是否会让你得到你想要的。

DECLARE @sourceTable TABLE (
    test1 int,
    test2 varchar(255)
);

DECLARE @destinationTable TABLE (testRow NVARCHAR(MAX));

INSERT @sourceTable  (test1, test2)
VALUES (5, 'something'),
       (6, 'something else');

WITH r AS (
    SELECT test1, test2, ROW_NUMBER() OVER (ORDER BY test1, test2) AS RowNum
    FROM @sourceTable 
)
INSERT @destinationTable (testRow)
SELECT (SELECT test1, test2 FROM r WHERE RowNum = r2.RowNum FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER)
FROM r r2;

SELECT testRow FROM @destinationTable;

由此产生的结果将是:

{"test1":5,"test2":"something"}
{"test1":6,"test2":"something else"}

如果您希望每一行都在一个数组中,请删除 WITHOUT_ARRAY_WRAPPER。

CTE 为每一行生成一个标识符,然后外部查询只为该单行生成 JSON。但是,这作为单个集合操作进行操作,因此随着源数据的增长将大大优于游标解决方案。每当您发现自己使用游标遍历表以选择或更新数据时,您都应该退后一步,寻找基于集合的方法。

【讨论】:

  • 另外,为了清楚起见,您可能应该从 @sourceTable 中删除 testRow
【解决方案2】:

我可能会迟到,但这可以帮助某人。 换行

SELECT @test1, @test2 FOR JSON AUTO

SELECT @test1, @test2 FOR JSON PATH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多