JSON_MODIFY 不适用于可变参数
JSON_MODIFY does not work with variable parameter
我有一个 SQL 查询修改了一些 JSON。我正在遍历数据并根据迭代修改 JSON 的一部分。
为此,我需要将可变参数传递给 JSON_MODIFY,但由于某些原因,它不起作用!
SET @json = JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
我还尝试将整个表达式作为变量传递:
DECLARE @hasAnswerPath VARCHAR(100);
SET @hasAnswerPath = '$.' + @ProKey + '.hasAnswer';
SET @json = JSON_MODIFY(@ProData, @hasAnswerPath, CAST(1 as BIT))
但它具有相同的输出,hasAnswer 被添加到 JSON 的根而不是@ProKey 指定的元素中。
这很好用:
SET @json = JSON_MODIFY(@ProData, '$.SomeName1.hasAnswer', CAST(1 as BIT))
好像@ProKey 被忽略了。
完成查询:
BEGIN TRAN
DECLARE @ProID as uniqueidentifier;
DECLARE @ProData as nvarchar(max);
DECLARE @ProKey as varchar(200);
DECLARE ProCursor CURSOR FOR
SELECT Id, [Data] FROM [dbo].[PRO]
OPEN ProCursor;
FETCH NEXT FROM ProCursor INTO @ProID, @ProData;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @json NVARCHAR(max);
DECLARE DataCursor CURSOR FOR
SELECT [key] FROM OPENJSON(@ProData) WHERE type = 5; --5 is object data
OPEN DataCursor;
FETCH NEXT FROM DataCursor INTO @ProKey;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @json=JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
SET @json=JSON_MODIFY(@json,'$.' + @ProKey + '.questionType','intro')
FETCH NEXT FROM DataCursor INTO @ProKey;
END;
UPDATE [dbo].[PRO]
SET [Data] = @json
WHERE Id = @ProID
PRINT @json
CLOSE DataCursor;
DEALLOCATE DataCursor;
FETCH NEXT FROM ProCursor INTO @ProID, @ProData;
END
CLOSE ProCursor;
DEALLOCATE ProCursor;
ROLLBACK
样本JSON:
{
"SomeName1": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 1.0
}
},
"SomeName2": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 4.0
}
},
"SomeName3": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 2.0
}
}
}
预期结果:
},
"SomeName1": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 1.0
}
"hasAnswer": true,
"questionType": "intro",
}
}
实际结果:
},
"SomeName1": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 1.0
}
}
},
"hasAnswer":true,
"questionType":"intro"
}
我做错了什么?
您似乎无意中覆盖了您的变量:
-- first iteration
SET @json=JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
-- @json contains the @prodata after modification to first key (@prodata itself is not changed)
SET @json=JSON_MODIFY(@json,'$.' + @ProKey + '.questionType','intro')
-- @json (its first key to be more precise) is modified further
但在下一次迭代中,此行会将修改后的 @json
还原为 @prodata
的原始值。只有最后一个键会保留修改:
-- second iteration
SET @json=JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
-- you just overwrote your modifications with the value inside @prodata
解决办法是稍微重新安排一下代码,可能是在循环外初始化@json
。
我有一个 SQL 查询修改了一些 JSON。我正在遍历数据并根据迭代修改 JSON 的一部分。
为此,我需要将可变参数传递给 JSON_MODIFY,但由于某些原因,它不起作用!
SET @json = JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
我还尝试将整个表达式作为变量传递:
DECLARE @hasAnswerPath VARCHAR(100);
SET @hasAnswerPath = '$.' + @ProKey + '.hasAnswer';
SET @json = JSON_MODIFY(@ProData, @hasAnswerPath, CAST(1 as BIT))
但它具有相同的输出,hasAnswer 被添加到 JSON 的根而不是@ProKey 指定的元素中。
这很好用:
SET @json = JSON_MODIFY(@ProData, '$.SomeName1.hasAnswer', CAST(1 as BIT))
好像@ProKey 被忽略了。
完成查询:
BEGIN TRAN
DECLARE @ProID as uniqueidentifier;
DECLARE @ProData as nvarchar(max);
DECLARE @ProKey as varchar(200);
DECLARE ProCursor CURSOR FOR
SELECT Id, [Data] FROM [dbo].[PRO]
OPEN ProCursor;
FETCH NEXT FROM ProCursor INTO @ProID, @ProData;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @json NVARCHAR(max);
DECLARE DataCursor CURSOR FOR
SELECT [key] FROM OPENJSON(@ProData) WHERE type = 5; --5 is object data
OPEN DataCursor;
FETCH NEXT FROM DataCursor INTO @ProKey;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @json=JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
SET @json=JSON_MODIFY(@json,'$.' + @ProKey + '.questionType','intro')
FETCH NEXT FROM DataCursor INTO @ProKey;
END;
UPDATE [dbo].[PRO]
SET [Data] = @json
WHERE Id = @ProID
PRINT @json
CLOSE DataCursor;
DEALLOCATE DataCursor;
FETCH NEXT FROM ProCursor INTO @ProID, @ProData;
END
CLOSE ProCursor;
DEALLOCATE ProCursor;
ROLLBACK
样本JSON:
{
"SomeName1": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 1.0
}
},
"SomeName2": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 4.0
}
},
"SomeName3": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 2.0
}
}
}
预期结果:
},
"SomeName1": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 1.0
}
"hasAnswer": true,
"questionType": "intro",
}
}
实际结果:
},
"SomeName1": {
"header": "Some text",
"answer": {
"type": "specified",
"numberValue": 1.0
}
}
},
"hasAnswer":true,
"questionType":"intro"
}
我做错了什么?
您似乎无意中覆盖了您的变量:
-- first iteration
SET @json=JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
-- @json contains the @prodata after modification to first key (@prodata itself is not changed)
SET @json=JSON_MODIFY(@json,'$.' + @ProKey + '.questionType','intro')
-- @json (its first key to be more precise) is modified further
但在下一次迭代中,此行会将修改后的 @json
还原为 @prodata
的原始值。只有最后一个键会保留修改:
-- second iteration
SET @json=JSON_MODIFY(@ProData, '$.' + @ProKey + '.hasAnswer', CAST(1 as BIT))
-- you just overwrote your modifications with the value inside @prodata
解决办法是稍微重新安排一下代码,可能是在循环外初始化@json
。