首页 > 解决方案 > SQL Sever 2016 - 行为不一致 - “JSON_VALUE 或 JSON_QUERY”的参数 2 必须是字符串文字

问题描述

我们使用的是 SQL Server 2016,我编写了一个使用以下代码的函数:

IF @JsonString IS NULL OR LTRIM(RTRIM(@JsonString)) = ''
BEGIN
   RETURN NULL;
END

DECLARE @ArrayValues VARCHAR(100);

SELECT @ArrayValues =   REPLACE(REPLACE(REPLACE(
                      JSON_QUERY(@JsonString, @JsonPathToArray)
                   ,'"', ''), '[', ''), ']', '');

RETURN @ArrayValues;

基本上,我得到了数组并删除了分隔字符。

我有 2 个使用此函数的存储过程。一个工作完美,另一个没有。

有任何想法吗?

标签: sqlsql-serverjson-query

解决方案


说明:

文档指出,您需要 SQL Server 2017+ 来提供一个...变量作为路径的值...这是对"The argument 2 of the "JSON_VALUE or JSON_QUERY" must be a string literal."您语句中错误的解释。

对于 SQL Server 2016,您可以使用OPENJSON()

DECLARE @ArrayValues VARCHAR(100)
DECLARE @JsonString VARCHAR(100) = '{"Key" :["a","b","c"]}'
DECLARE @JsonPathToArray VARCHAR(100) = '$.Key'

SELECT @ArrayValues = REPLACE(REPLACE(REPLACE(
                         JSON_QUERY([value])
                      ,'"', ''), '[', ''), ']', '')
FROM OPENJSON(@JsonString)                      
WHERE CONCAT('$.', [key]) = @JsonPathToArray
                      
SELECT @ArrayValues

补充说明:

请注意,您当前方法中的语句会替换每次出现的",[]字符,即使这些字符是 JSON 值的一部分。

所以,问题的陈述:

DECLARE @ArrayValues VARCHAR(100)
DECLARE @JsonString VARCHAR(100) = '{"Key" :["a","b","c","EscapedContent\"[]"]}'
DECLARE @JsonPathToArray VARCHAR(100) = '$.Key'

SELECT @ArrayValues = REPLACE(REPLACE(REPLACE(
                         JSON_QUERY(@JsonString, @JsonPathToArray)
                      ,'"', ''), '[', ''), ']', '');
SELECT @ArrayValues

返回:

a,b,c,EscapedContent\

如果您想从一个 JSON 数组聚合项目,您可以尝试另一种方法(再次需要 SQL Server 2017+):

DECLARE @ArrayValues VARCHAR(100)
DECLARE @JsonString VARCHAR(100) = '{"Key" :["a","b","c", "EscapedContent\"[]"]}'
DECLARE @JsonPathToArray VARCHAR(100) = '$.Key'

SELECT @ArrayValues = STRING_AGG([value], ',') WITHIN GROUP (ORDER BY CONVERT(int, [key])) 
FROm OPENJSON(@JsonString, @JsonPathToArray)
SELECT @ArrayValues

结果:

a,b,c,EscapedContent"[]

推荐阅读