web-dev-qa-db-ja.com

SQL to JSON-SQL 2016のオブジェクトの配列から値の配列へ

SQL 2016には、SQLサーバー上のデータをJSONに変換する新しい機能があります。オブジェクトの配列を値の配列に結合するのが困難です

例-

CREATE TABLE #temp (item_id VARCHAR(256))

INSERT INTO #temp VALUES ('1234'),('5678'),('7890')

SELECT * FROM #temp

--convert to JSON

SELECT (SELECT item_id 
FROM #temp
FOR JSON PATH,root('ids')) 

結果-

{
    "ids": [{
        "item_id": "1234"
    },
    {
        "item_id": "5678"
    },
    {
        "item_id": "7890"
    }]
}

しかし、結果は-

"ids": [
        "1234",
        "5678",
        "7890"
    ]

誰か助けてくれますか?

ありがとう!私たちが見つけた解決策は、最初にXMLに変換することです-

SELECT  
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"' 
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids  
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER 

マーティン!

これはもっと簡単な方法だと思います:

    SELECT '"ids": ' + 
    REPLACE( 
      REPLACE( (SELECT item_id FROM #temp FOR JSON AUTO),'{"item_id":','' ),
      '"}','"' )
12
Magne Rekdal
declare @temp table (item_id VARCHAR(256))

INSERT INTO @temp VALUES ('123"4'),('5678'),('7890')

SELECT * FROM @temp

--convert to JSON

select 
    json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', char(44)))) as [json]
from @temp
for json path

文字列をjson配列として連結する場合:

1)エスケープ文字列-STRING_ESCAPE

2)文字列をコンマ区切りで連結-STRING_AGG、コンマASCIIコードは44

3)引用符を括弧内に追加します-QUOTENAME(paramなし)

4)JSON(要素の配列を含む)をJSONとして返す-JSON_QUERY

6
massther

プリミティブ値の配列は有効なJSONであるため、プリミティブ値の配列を選択する機能がSQL ServerのJSON機能に組み込まれていないのは奇妙に思えます。 (逆に、そのような機能が存在する場合、私は少なくともかなりの検索の後にそれを発見することができませんでした)。

上記のアプローチは、説明どおりに機能します。しかし、より大きなクエリのフィールドに適用される場合、プリミティブの配列は引用符で囲まれます。

例えば、これ

DECLARE @BomTable TABLE (ChildNumber dbo.udt_ConMetPartNumber);
INSERT INTO @BomTable (ChildNumber) VALUES (N'101026'), (N'101027');
SELECT N'"Children": ' + REPLACE(REPLACE((SELECT ChildNumber FROM @BomTable FOR JSON PATH), N'{"ChildNumber":', N''), '"}','');

生産によって動作します:

"Children": ["101026,"101027]

しかし、上記のアプローチに従って、これ:

SELECT
    p.PartNumber,
    p.Description,
    REPLACE(REPLACE((SELECT
                        ChildNumber
                     FROM
                        Part.BillOfMaterials
                     WHERE
                        ParentNumber = p.PartNumber
                     ORDER BY
                        ChildNumber
                    FOR
                     JSON AUTO
                    ), N'{"ChildNumber":', N''), '"}', '"') AS [Children]
FROM
    Part.Parts AS p
WHERE
    p.PartNumber = N'104444'
FOR
    JSON PATH

生産物:

[
    {
        "PartNumber": "104444",
        "Description": "ASSY HUB           R-SER  DRIV HP10  ABS",
        "Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
    }
]

Children配列は文字列としてラップされます。

4
CalvinDale

これらのソリューションのほとんどは、基本的に配列の内容を表すCSVを作成し、そのCSVを最終的なJSON形式に入れます。 XMLを避けるために私が使用するものは次のとおりです。

DECLARE @tmp NVARCHAR(MAX) = ''

SELECT @tmp = @tmp + '"' + [item_id] + '",'
FROM #temp -- Defined and populated in the original question

SELECT [ids] = JSON_QUERY((
    SELECT CASE
        WHEN @tmp IS NULL THEN '[]'
        ELSE '[' + SUBSTRING(@tmp, 0, LEN(@tmp)) + ']'
        END
    ))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
1
Eric