2016-07-09 107 views
5

Sono bloccato durante l'accesso alla matrice all'interno di JSON utilizzando la funzione JSON_VALUE appena introdotta. Si prega di prendere in considerazione seguente codice -Accesso alla matrice JSON in SQL Server 2016 utilizzando 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; 

qui se voglio accedere numero di telefono specifico del solito la sintassi di accesso a questo nodo non sta funzionando. Sto ottenendo seguente errore in questo caso

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

Anche quando ho controllato a http://jsonpath.com, sono in grado di recuperare il valore. SQL Server 2016 utilizza una sintassi diversa per accedere ai valori JSON?

+0

Questo è off-topic, ma potrebbe essere utile per know.You può usare DROP TABLE SE EXISTS JsonData invece di if (select) drop table .... –

+0

D'accordo, vecchie abitudini morire duramente :-) –

risposta

4

per ottenere tutti da phoneNumbers:

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

Grazie ancora! Sembra che sia il più vicino Posso ottenere un sacco di modifiche necessarie se non conosco la struttura esatta di JSON fornita, ma i vostri suggerimenti mi hanno aiutato nella giusta direzione: volevo creare una soluzione generica, mi auguro che gli aggiornamenti futuri possano supportare il corretto attraversamento JSON. –

2

SQL Server 2016 supporta JSON. È molto simile, quasi identico. Farai il tuo confronto.

Non è necessario utilizzare una variabile temp @Table e poi fare manipolazioni ...

basta eseguire le seguenti query

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 

Guarda anche questi collegamenti ufficiali di Microsoft, circa il supporto di JSON per maggiori dettagli:

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

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

+0

Ciao, grazie per l'aiuto! Avevo bisogno della variabile @table perché la mia soluzione originale aveva bisogno di un parametro in cui l'app potesse passare qualsiasi percorso JSON. I dati relativi a quel percorso passato devono essere restituiti da un JSON complesso (MUCH). È un esempio semplificato e fondamentalmente ho bisogno di restituire tutti gli elementi se l'array è fornito come argomento. Ad esempio, $ .phoneNumbers [:]. Numero dovrebbe restituire tutti i numeri in quell'array. –

+0

Aham, quindi sei molto vicino alla soluzione. Userò le query (o i percorsi) sopra in una query sql dinamica mentre stai provando nella tua query. Sappi che $ .phoneNumbers [:] in T-SQL JSON è in realtà $ .phoneNumbers [*] –

+0

Grazie ancora! Ho avuto un errore in seguito quando ho provato a usare * - Msg 13607, Level 16, State 4, Line 4 Il percorso JSON non è formattato correttamente. Il carattere imprevisto '*' si trova nella posizione 15. Se potessi, per piacere, indicarmi un link che spieghi "TSQL JSON" che sarebbe davvero utile. Non sono riuscito a trovare alcun riferimento simile –

2

È possibile utilizzare "CROSS APPLY" per ottenere i numeri di telefono con il cognome:

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