2017-02-07 2 views
3

Ich arbeite an einem Projekt, in dem ich empfangene und konsumieren (d. H. Informationen extrahieren) von empfangenen JSONs benötigen. Die aktuelle Version von SQL Server, die ich verwende (und wird sich in den nächsten Jahren nicht ändern), ist 2012, das keine Unterstützung dafür enthält (im Gegensatz zur Version 2016).JSON in SQL Server 2012 konsumieren

Ich erinnere mich, einen Beitrag von jemandem zu sehen, in dem er sanft einen Quellcode dafür angeboten hat, aber leider nicht wieder finden kann.

Hat jemand eine funktionierende Lösung?

Die Idee ist, etwas zu haben, wie:

die folgende JSON Mit:

{ 
    "Obj1": { 
     "Obj1_S_1": [{ 
      "Obj1_S_1_S_1": "Blabla_1" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_2" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_3" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_4" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_5" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_6" 
     }] 
    }, 
    "Obj2": "This is a simple string", 
    "Obj3": "456.33" 
} 

Ich kann den folgenden Aufruf verwenden:

SET @My_Param = GET_JSON(@Source_JSON, '*.Obj1.Obj1_S_1[3].Obj1_S_1_S_1') ; 

und ich würde den Wert 'Blabla_4' in erhalten die Variable @My_Param.

Dies ist die gleiche Syntax, die übrigens in Oracle und MySQL verwendet wird.

Vorschläge, die den spezifischen Bedarf ansprechen, werden sehr geschätzt.

+2

Dies ist die beste Ressource, die ich kenne, um JSON vor 2016 zu implementieren: [JSON-Zeichenfolgen in SQL Server verwenden - Phil Factor] (https://www.simple-talk.com/sql/t-sql-programming/ using-json-strings-in-sql-server /), [Erstellen von JSON-Dokumenten aus SQL Server-Abfragen über TSQL - Phil Factor] (https://www.simple-talk.com/sql/t-sql-programming/ Produzieren-JSON-Dokumente-von-SQL-Server-Abfragen-via-TSQL /) , [SQL Server JSON zu Tabelle und Tabelle zu JSON - Phil Factor] (https://www.simple-talk.com/blogs/ sql-server-json-zu-tabelle und tabelle-zu-json /) – SqlZim

+0

Vielen Dank @SqlZim für Ihren Vorschlag. Ich habe diesen Vorschlag gesehen, aber es ist nicht das, wonach ich suche (vielleicht verstehe ich es nicht vollständig).Zwei Hauptgründe: (1) Es durchläuft den gesamten JSON unabhängig davon, was Sie wirklich brauchen (vielleicht nur das erste Element), und (2) es konvertiert den JSON in eine Art TABLE, und meine Frage ist, wie das Ergebnis aussehen würde wenn der JSON, sagen wir, 6 verschiedene Hierarchieebenen hat (zB Arrays innerhalb von Arrays innerhalb von Arrays ....). – FDavidov

Antwort

0

kann mit einigen strategischen Parse/split Manipulation

Beispieldaten

Declare @S varchar(max) =' 
{ 
    "Obj1": { 
     "Obj1_S_1": [{ 
      "Obj1_S_1_S_1": "Blabla_1" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_2" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_3" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_4" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_5" 
     }, { 
      "Obj1_S_1_S_1": "Blabla_6" 
     }] 
    }, 
    "Obj2": "This is a simple string", 
    "Obj3": "456.33" 
} 
' 

Beispiel

--Clean-up JSON String and add '|||' as a standard delimeter 
Select @S = Replace(@S,MapFrm,MapTo) 
From (values ('"'  ,'') 
      ,(char(13),'|||') 
      ,(char(10),'|||') 
      ,('}'  ,'|||') 
      ,('{'  ,'|||') 
      ,('['  ,'|||') 
      ,(']'  ,'|||') 
     ) b (MapFrm,MapTo) 

Option mit einem Parse/Split UDF

erfolgen
Select Item = left(RetVal,charindex(':',RetVal+':')-1) 
     ,Value = ltrim(right(RetVal,len(RetVal)-charindex(':',RetVal+':'))) 
From [dbo].[udf-Str-Parse](@S,'|||') 
Where Len(IsNull(RetVal,' '))>1 
Order By RetSeq 

Option ohne Parse/Split UDF

Select Item = left(RetVal,charindex(':',RetVal+':')-1) 
     ,Value = ltrim(right(RetVal,len(RetVal)-charindex(':',RetVal+':'))) 
From (
     Select RetSeq = Row_Number() over (Order By (Select null)) 
       ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
     From (Select x = Cast('<x>' + replace((Select replace(@S,'|||','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
     Cross Apply x.nodes('x') AS B(i) 
     ) A 
Where Len(IsNull(RetVal,' '))>1 
Order By RetSeq 

Beide Return

Item   Value 
Obj1  
Obj1_S_1  
Obj1_S_1_S_1 Blabla_1 
Obj1_S_1_S_1 Blabla_2 
Obj1_S_1_S_1 Blabla_3 
Obj1_S_1_S_1 Blabla_4 
Obj1_S_1_S_1 Blabla_5 
Obj1_S_1_S_1 Blabla_6 
Obj2   This is a simple string, 
Obj3   456.33 

Die UDF wenn benötigt

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return ( 
    Select RetSeq = Row_Number() over (Order By (Select null)) 
      ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
    From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i) 
); 
--Thanks Shnugo for making this XML safe 
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ') 
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',') 
+0

Vielen Dank John für Ihren Beitrag, aber ich sehe einige Probleme damit: (1) Sie schlagen vor, sowohl '{'/'}' und '['/']' zu '|||' zu ändern und damit den Unterschied zu verlieren zwischen einer ** Struktur ** und einem ** Array ** (möglicherweise Strukturen); (2) Stellen Sie sich vor, dass es eine Hierarchie gibt, so dass (zum Beispiel) "Obj2" auch ein Array ist, das ähnlich wie "Obj1" ist, und Sie müssen bestimmte Elemente von jedem der beiden Arrays fischen. Jede Lösung ** muss ** die ursprüngliche Struktur des JSON respektieren, und ich sehe nicht, wie Ihr Vorschlag es tut. Vielleicht vermisse ich etwas ... bin ich? – FDavidov