SQL 2016 verfügt über eine neue Funktion, mit der Daten auf SQL Server in JSON konvertiert werden. Ich habe Schwierigkeiten, ein Array von Objekten zu einem Array von Werten zu kombinieren, d.h.
BEISPIEL -
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'))
ERGEBNIS -
{
"ids": [{
"item_id": "1234"
},
{
"item_id": "5678"
},
{
"item_id": "7890"
}]
}
Aber ich möchte das Ergebnis als -
"ids": [
"1234",
"5678",
"7890"
]
Kann mir bitte jemand helfen?
Vielen Dank! Die Lösung, die wir gefunden haben, konvertiert zuerst in XML -
SELECT
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"'
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER
Martin!
Ich glaube, das ist noch einfacher:
SELECT '"ids": ' +
REPLACE(
REPLACE( (SELECT item_id FROM #temp FOR JSON AUTO),'{"item_id":','' ),
'"}','"' )
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
Wenn wir Strings als JSON-Array verketten wollen, dann:
1) Escape-Zeichenfolge - STRING_ESCAPE
2) String mit Komma-Trennzeichen verketten - STRING_AGG, Komma-ASCII-Code ist 44
3) Anführungszeichen in Klammern setzen - QUOTENAME (ohne Parameter)
4) gebe einen String (mit einem Array von Elementen) als json - JSON_QUERY zurück
Da Arrays mit primitiven Werten gültiges JSON sind, scheint es seltsam, dass eine Funktion zum Auswählen von Arrays mit primitiven Werten nicht in die JSON-Funktionalität von SQL Server integriert ist. (Wenn im Gegenteil eine solche Funktionalität vorhanden ist, konnte ich sie nach längerer Suche zumindest nicht entdecken.).
Der oben beschriebene Ansatz funktioniert wie beschrieben. Wenn Sie jedoch ein Feld in einer größeren Abfrage anwenden, wird das Array der Grundelemente in Anführungszeichen gesetzt.
Zum Beispiel dieses
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''), '"}','');
arbeitet durch das Produzieren:
"Children": ["101026,"101027]
Aber wie oben beschrieben:
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
Produziert:
[
{
"PartNumber": "104444",
"Description": "ASSY HUB R-SER DRIV HP10 ABS",
"Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
}
]
Wobei das Children -Array als Zeichenfolge umbrochen wird.
Die meisten dieser Lösungen erstellen im Wesentlichen eine CSV, die den Array-Inhalt darstellt, und setzen diese CSV dann in das endgültige JSON-Format. Folgendes verwende ich, um XML zu vermeiden:
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