为什么 CASE 语句中的 JSON_QUERY 无法删除转义字符?

you*_*gme 5 sql-server t-sql json sql-server-2016

json_query如果在case语句中应用该函数,则似乎无法删除双引号字符 (") 的转义字符。

下面的示例代码。

declare @data nvarchar(max);
declare @debug int = 0;

set @data = '{"id":10}';

set @debug = 0;
select
    isjson(@data) as 'validateData',
    @data as 'unprocessedSourceData',
    json_query(@data) as 'processedSourceData',
    case when @debug = 1 then json_query(@data) else null end as 'conditionallyProcessedSourceData'
    for json path, without_array_wrapper ;

set @debug = 1;
select
    isjson(@data) as 'validateData',
    @data as 'unprocessedSourceData',
    json_query(@data) as 'processedSourceData',
    case when @debug = 1 then json_query(@data) else null end as 'conditionallyProcessedSourceData'
    for json path, without_array_wrapper ;
Run Code Online (Sandbox Code Playgroud)

第一个查询的结果:

{"validateData":1,"unprocessedSourceData":"{\"id\":10}","processedSourceData":{"id":10}}
Run Code Online (Sandbox Code Playgroud)

第二个查询的结果:

{"validateData":1,"unprocessedSourceData":"{\"id\":10}","processedSourceData":{"id":10},"conditionallyProcessedSourceData":"{\"id\":10}"}
Run Code Online (Sandbox Code Playgroud)

注意最后的转义字符:“ {\"id\":10}

1)为什么会这样?

2)如何返工此查询,这样,如果@debug = 1conditionallyProcessedSourceData元素包含有效的JSON,如果@debug = 0再元素null

Mik*_*son 7

来自JSON_QUERY (Transact-SQL)

返回 nvarchar(max) 类型的 JSON 片段。

JSON_QUERY 返回一个有效的 JSON 片段。因此,FOR JSON 不会转义 JSON_QUERY 返回值中的特殊字符。

所以for json path逃脱nvarchar(max),除非数据nvarchar(max)数据来自json_query()

在您的查询中,数据来自 case 语句,而不是直接来自json_query.

您可以采取的解决方法是将其置于json_query案例之外。

json_query(case when @debug = 1 then @data else null end)
Run Code Online (Sandbox Code Playgroud)

将其合并到您的完整脚本中,以便您可以比较不同的方法,给出:

declare @data nvarchar(max);
declare @debug int = 0;

set @data = '{"id":10}';

set @debug = 0;
select
    isjson(@data) as 'validateData',
    @data as 'unprocessedSourceData',
    json_query(@data) as 'processedSourceData',
    case when @debug = 1 then json_query(@data) else null end as 'conditionallyProcessedSourceData', 
    json_query(case when @debug = 1 then @data else null end) as 'caseResultProcessed'
    for json path, without_array_wrapper ;

set @debug = 1;
select
    isjson(@data) as 'validateData',
    @data as 'unprocessedSourceData',
    json_query(@data) as 'processedSourceData',
    case when @debug = 1 then json_query(@data) else null end as 'conditionallyProcessedSourceData', -- This was the issue
    json_query(case when @debug = 1 then @data else null end) as 'caseResultProcessed' -- This is the solution
    for json path, without_array_wrapper ;
Run Code Online (Sandbox Code Playgroud)