2016-07-09 8 views
5

Ich bin beim Zugriff auf Array in JSON mit der neu eingeführten JSON_VALUE-Funktion fest. Bitte beachten Sie folgenden Code -Zugriff auf JSON-Array in SQL Server 2016 mithilfe von JSON_VALUE

IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='JsonData') 
    DROP TABLE JsonData; 
go 

CREATE TABLE JsonData(JsonData nvarchar(max)); 
DECLARE @SQL nvarchar(max); 
DECLARE @Table AS TABLE(JsonPath VARCHAR(256)); 

INSERT INTO JsonData(JsonData) 
VALUES(
'{ 
    "firstName": "John", 
    "lastName" : "doe", 
    "age"  : 26, 
    "address" : { 
    "streetAddress": "naist street", 
    "city"   : "Nara", 
    "postalCode" : "630-0192" 
    }, 
    "phoneNumbers": [ 
    { 
     "type" : "iPhone", 
     "number": "0123-4567-8888" 
    }, 
    { 
     "type" : "home", 
     "number": "0123-4567-8910" 
    } 
    ] 
}') 


INSERT INTO @Table 
SELECT VALUE FROM OPENJSON('{ 
"Path1":"$.firstName","Path2":"$.phoneNumbers[:1].number" 
}') ; 

SELECT @SQL=(SELECT 'UNION SELECT '''+ CAST(JsonPath AS VARCHAR(256)) +''',JSON_VALUE(JsonData,'''+a.JsonPath+''') 
        FROM JsonData a'        
        FROM @Table a  
     FOR XML PATH(''), TYPE) 
    .value('.','NVARCHAR(MAX)') 
FROM @Table t; 

SELECT @SQL=RIGHT(@SQL,LEN(@SQL)-5) 

PRINT @SQL  

EXEC SP_EXECUTESQL @SQL; 

Hier Wenn ich bestimmte Telefonnummer dann üblichen Syntax für den Zugriff auf diese Knoten nicht funktioniert zugreifen möchten. Ich erhalte folgende Fehlermeldung in diesem Fall

JSON path is not properly formatted. Unexpected character ':' is found at position 15. 

Obwohl, wenn ich bei http://jsonpath.com geprüft, ich bin in der Lage Wert abzurufen. Verwendet SQL Server 2016 eine andere Syntax für den Zugriff auf JSON-Werte?

+0

Dies ist off-topic, aber vielleicht zu know.You nützlich seinem kann DROP TABLE IF EXISTS JsonData anstelle von wenn (wählen) Drop-Tabelle .... –

+0

Einverstanden, alte Gewohnheiten sterben hart :-) –

Antwort

4

Um all von phonenumbers zu erhalten:

DECLARE @json nvarchar(max)= 
    '{ 
     "firstName": "John", 
     "lastName" : "doe", 
     "age"  : 26, 
     "address" : { 
     "streetAddress": "naist street", 
     "city"   : "Nara", 
     "postalCode" : "630-0192" 
     }, 
     "phoneNumbers": [ 
     { 
      "type" : "iPhone", 
      "number": "0123-4567-8888" 
     }, 
     { 
      "type" : "home", 
      "number": "0123-4567-8910" 
     } 
     ] 
    }' 

    SELECT [Type], [Number] 
    FROM OPENJSON(@json, '$.phoneNumbers') 
    WITH ([Type] NVARCHAR(25) '$.type', [Number] NVARCHAR(25) '$.number'); 
+0

Danke nochmal! Sieht aus wie es am nächsten ist Ich kann das. Es wird eine Menge Optimierungen geben, wenn ich nicht genau die Struktur von JSON kenne, aber Ihre Vorschläge haben mir in die richtige Richtung geholfen. Ich wollte generische Lösungen erstellen. Ich wünsche, dass zukünftige Updates das richtige JSON-Traversing unterstützen. –

2

SQL Server 2016 unterstützt JSON. Es ist sehr ähnlich, fast identisch. Sie werden Ihren eigenen Vergleich machen.

Sie können eine temporäre Variable @Table und dann machen Manipulationen verwenden müssen ...

Führen Sie einfach die folgenden Abfragen

SELECT JSON_VALUE(JsonData, '$.phoneNumbers[0].type') AS [PhoneType], 
     JSON_VALUE(JsonData, '$.phoneNumbers[0].number') AS [PhoneNumber] 
FROM JsonData 
WHERE ISJSON(JsonData) > 0; 
--iPhone 0123-4567-8888 

SELECT JSON_VALUE(JsonData, '$.phoneNumbers[1].type') AS [PhoneType], 
     JSON_VALUE(JsonData, '$.phoneNumbers[1].number') AS [PhoneNumber] 
FROM JsonData 
WHERE ISJSON(JsonData) > 0; 
--home 0123-4567-8910 

Schauen Sie sich diese offiziellen Links von Microsoft aus, über JSON-Unterstützung für weitere Informationen:

https://msdn.microsoft.com/en-us/library/dn921897.aspx

https://msdn.microsoft.com/en-us/library/dn921898.aspx

+0

Hallo, Vielen Dank für Ihre Hilfe! Ich brauchte die @table-Variable, da meine ursprüngliche Lösung einen Parameter benötigt, in dem die App einen beliebigen JSON-Pfad übergeben kann. Daten gegen diesen übergebenen Pfad sollten von einem (VIEL) komplexen JSON zurückgegeben werden. Es ist ein vereinfachtes Beispiel und ich muss im Grunde alle Elemente zurückgeben, wenn Array als Argument zur Verfügung gestellt wird. Zum Beispiel sollte $ .phoneNumbers [:]. Number alle Zahlen in diesem Array zurückgeben. –

+0

Aham, dann bist du der Lösung sehr nahe. Ich würde die obigen Abfragen (oder Pfade) in einer dynamischen SQL-Abfrage verwenden, wie Sie es in Ihrer Abfrage versuchen. Wissen, dass $ .phoneNumbers [:] in T-SQL JSON ist eigentlich $ .phoneNumbers [*] –

+0

Danke nochmal! Ich habe folgende Fehlermeldung erhalten, wenn ich versucht habe, * zu verwenden - Msg 13607, Level 16, Status 4, Zeile 4 Der JSON-Pfad wurde nicht richtig formatiert. Unerwartetes Zeichen '*' wird an Position 15 gefunden. Wenn Sie mich bitte auf einen Link verweisen könnten, der "TSQL JSON" erklärt, wäre das wirklich hilfreich. Ich konnte keine solche Referenz finden –

2

You "CROSS APPLY" verwenden kann, um die Telefonnummern mit Vornamen zu bekommen:

SELECT JSON_VALUE (jsonData, '$.firstName'),p.* 
    FROM JsonData 
    CROSS APPLY 
    OPENJSON (JsonData, '$.phoneNumbers') WITH(type varchar(10) '$.type', number varchar (30) '$.number') p