関数がcase
ステートメント内で適用されている場合、json_query
は二重引用符( ")のエスケープ文字を削除できないようです。
以下のサンプルコード。
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 ;
最初のクエリの結果:
{"validateData":1,"unprocessedSourceData":"{\"id\":10}","processedSourceData":{"id":10}}
2番目のクエリの結果:
{"validateData":1,"unprocessedSourceData":"{\"id\":10}","processedSourceData":{"id":10},"conditionallyProcessedSourceData":"{\"id\":10}"}
末尾のエスケープ文字に注意してください: "{\"id\":10}
"
1)なぜそうなのでしょうか?
2)@debug = 1
の場合、conditionallyProcessedSourceData
要素に有効なJSONが含まれ、@debug = 0
の場合、要素がnull
になるように、このクエリを再作成するにはどうすればよいですか?
From JSON_QUERY(Transact-SQL) から
タイプnvarchar(max)のJSONフラグメントを返します。
そして
JSON_QUERYは有効なJSONフラグメントを返します。その結果、FOR JSONはJSON_QUERY戻り値の特殊文字をエスケープしません。
したがって、nvarchar(max)
データがnvarchar(max)
からのものでない限り、_for json path
_はjson_query()
データをエスケープします。
クエリでは、データは、_json_query
_から直接ではなく、caseステートメントから取得されます。
あなたができる回避策は、ケースの外に_json_query
_を置くことです。
_json_query(case when @debug = 1 then @data else null end)
_
これを完全なスクリプトに組み込んで、さまざまなアプローチを比較できるようにすると、次のようになります。
_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 ;
_