#sqlsatParma#sqlsat462November 28°, 2015
SQL Server 2016: supporto nativo JSONAlessandro [email protected]://speakerscore.com/SQL16JSON
#sqlsatParma#sqlsat462November 28°, 2015
Alessandro Alpi | @suxstellinoMicrosoft MVP – SQL Server dal 2008
Blog ITA: http://blogs.dotnethell.it/suxstellinoBlog ENG: http://suxstellino.wordpress.com/Website: http://www.alessandroalpi.net
CTO Engage IT Services S.r.l.www.engageitservices.itTeam leader (SCRUM)
CommunitiesGetlatestversion.it
#sqlsatParma#sqlsat462November 28°, 2015
PremessaSOLO SQL Server 2016
Da CTP 2, ora CTP 3 Soggetto a cambiamentiFeature che devono “maturare” (V1)
#sqlsatParma#sqlsat462November 28°, 2015
AgendaIntroduzione al formato JSON
DefinizioniJSON vs XML
JSON dal punto di vista di SQL ServerCaratteristicheFunzionalità di export Funzionalità di import
Considerazioni generaliIndicizzazioneLimitazioni
#sqlsatParma#sqlsat462November 28°, 2015
Supporto per il formato JSON nativoA partire da SQL Server 2016
Dalla CTP 2Prima di 2016, T-SQL complesso e CPU intensiveAnche in tabelle In-Memory OLTP
Nessuna implementazione sullo storageNon è un tipo di dato come XMLÈ una stringa, si gestisce con (n)varchar()Parser nativo al momento dell’esecuzione della queryPer ora, qualora richiesto, proporre su CONNECT
#sqlsatParma#sqlsat462November 28°, 2015
JSON – Funzionalità chiave
SQL Server come hybrid storage engineRelational data – tablesNon-relational data – JSON, XML
#sqlsatParma#sqlsat462November 28°, 2015
JSON – concettiDefinizione
Acronimo di JavaScript Object NotationBasato su JavaScript, ma indipendenteTipi di dato comuni: bool, int, real, string, array, nullStringa, non markupEsempio:
{“first”: “Alessandro”,“last”: “Alpi”“age”: “34”,“courses”: [
{“code”: “C001”, “name”: “SQL Server Querying”},{“code”: “C002”, “name”: “Administering SQL Server”},{“code”: “C003”, “name”: “Troubleshooting SQL Server”},
]}
#sqlsatParma#sqlsat462November 28°, 2015
JSON – concettiPerchè utilizzare JSON
Estremamente leggero e semplicePerfetto per la rappresentazione dei datiLeggibile ed autodescrittivo/Portabile (può sostituire XML)Ottimo per AJAX/Javascript
Notazioni“ per “name” e “value”: per “name”:”value”Special char rappresentati con escape (\r, \t, ecc.){ } object (graffe)[ , ] array (quadre)[ { }, { } ] array di object
#sqlsatParma#sqlsat462November 28°, 2015
FormatoConversioni (CLR non supportato)
nvarchar, varchar, nchar, char -> stringint, bigint, float, decimal, numeric -> numberbit -> Boolean (true, false)datetime, date, datetime2, time, datetimeoffset -> stringUniqueidentifier, money, binary -> string e BASE64 string
#sqlsatParma#sqlsat462November 28°, 2015
JSON vs XML
JSONFormato leggeroText basedParser integrato query
ProcessingJsonPath/T-SQLIndici “normali”
XMLFunzionalità moltepliciTipizzazione forteParser DOM
ProcessingXPath/XQuery/T-SQL Indici XML dedicati
#sqlsatParma#sqlsat462November 28°, 2015
SQL Server vs DocumentDB
SQL ServerMotore ibridoTabelle e JSON stringFunzionalità generiche
Query ProcessingT-SQL completoIndici “normali”Supporto alle collation
DocumentDBMotore JSON Solo e specializzato per JSONOttimizzato per le scritture
ProcessingSQL per DocumentDB Indici “automatici”
#sqlsatParma#sqlsat462November 28°, 2015
FunzionalitàExport
FOR JSONImport
OPENJSONUtility
ISJSON (anche DDL)JSON_VALUE (anche DDL)JSON_QUERYDenormalizzazione
#sqlsatParma#sqlsat462November 28°, 2015
Funzionalità di exportClausola “FOR JSON”
PATHFOR JSON PATH
AUTOFOR JSON AUTO
UtilitàOpzione ROOT
FOR JSON AUTO, ROOT('info')
Opzione INCLUDE_NULL_VALUESFOR JSON AUTO, INCLUDE_NULL_VALUES
[ { "Number":"SO43659", "Date":"2011-05-31T00:00:00" "AccountNumber":"AW29825", "Price":59.99, "Quantity":1 }, { "Number":"SO43661", "Date":"2011-06-01T00:00:00“ "AccountNumber":"AW73565“, "Price":24.99, "Quantity":3 }]
SELECT * FROM myTable
FOR JSON AUTO
#sqlsatParma#sqlsat462November 28°, 2015
FOR JSON PATHRisultati
Senza FROM: singoli oggetti JSONCon FROM: array di oggetti JSONOgni colonna di un record è una proprietà sul JSON
NestingAlias con “.” come separatore per profonditàSubquery per sotto-oggetti JSON
#sqlsatParma#sqlsat462November 28°, 2015
FOR JSON AUTORisultati
Render basato su ordine di colonne/tabelleDisponibile solo con FROM
Render immodificabile Ogni colonna è una proprietà sul JSON
NestingIn caso di JOIN, la prima tabella è root, la seconda è nestedSubquery
#sqlsatParma#sqlsat462November 28°, 2015
Come usare JSON output in .net
Si usa StringBuilder()var cmd = new SqlCommand(queryWithForJson, conn);conn.Open();var jsonResult = new StringBuilder();var reader = cmd.ExecuteReader();if (!reader.HasRows())jsonResult.Append("[]");else{ while reader.Read() { jsonResult.Append(reader.GetValue(0).ToString()); }}
Empty JSON
Append rows
#sqlsatParma#sqlsat462November 28°, 2015
FORMATTARE ED ESPORTARE JSON DA SQL SERVER
DEMO
Utilizzo delle funzionalità di export
#sqlsatParma#sqlsat462November 28°, 2015
Funzionalità di importTrasformare ed importare
TVF OPENJSON()Consente un filtroSintassi JS ($.Collezione.Proprietà)… FROM OPENJSON (@JSalestOrderDetails, '$.OrdersArray') WITH (definition);
Perchè usarla?Caricare in tabellaAnalizzare colonne
SELECT * FROM OPENJSON(@json)
[ { "Number":"SO43659", "Date":"2011-05-31T00:00:00" "AccountNumber":"AW29825", "Price":59.99, "Quantity":1 },…]
#sqlsatParma#sqlsat462November 28°, 2015
Funzionalità di importAltre funzioni
Validation: ISJSON( json_text ) Importante per CHECK CONSTRAINT… WHERE ISJSON(tab.JCol) > 0
Querying: JSON_VALUE( json_text, path )Estrae uno scalare dal json letto e può filtrare per path… AND JSON_VALUE(tab.JCol,'$.Order.Type') = 'C‘
Querying: JSON_QUERY( json_text, path )Estrae un oggetto dal json letto e può filtrare per path… AND JSON_QUERY(tab.JCol,'$') = '{…}‘ (intero JSON)
#sqlsatParma#sqlsat462November 28°, 2015
Sintassi pathEspressioni di path
$ (intero JSON text), è il primo carattere di ricerca$.prop1 (proprietà del JSON)$[n] (ennesimo elemento nell’array JSON)$.prop1.prop2.array1[n].prop3.array[2].prop4 (traversing)Lax (default) e strict mode supportati
Differenza di gestione dei path non trovati (null vs error)In caso di duplicati, viene tornata la prima occorrenza
#sqlsatParma#sqlsat462November 28°, 2015
FORMATTARE ED ESPORTARE JSON DA SQL SERVER
DEMO
Utilizzo delle funzionalità di import
#sqlsatParma#sqlsat462November 28°, 2015
Impieghi possibiliEstensioni di record
Tabella con campi comuni + estensione JSONTrasformazioni
Lettura informazioni di “log”Serializzazione
Fornitura di un formato altamente “digeribile” dalle piattaformePassaggio dati a Integration Services
#sqlsatParma#sqlsat462November 28°, 2015
Operazioni non consigliateJSON su tutto
Fare troppi/solo oggetti contenenti chiavi e oggetti
SQL Server è RDBMS, non Key Value Store (es: Redis)Salvare le informazioni di continuo come JSON
Costa in termini di CPU, seppure poco (singolarmente) andare ad interpretarlo
Tutte le query con FOR JSONJSON dovrebbe essere una utilità, non una regolaSQL non è un server creato per serializzare JSON
#sqlsatParma#sqlsat462November 28°, 2015
IndicizzazioneNessuna modifica allo storage
Non è un tipo, è solo una stringaL’indicizzazione è quella che si farebbe su campi (n)(var)charAnche full-text
Tecniche di indicizzazioneJSON_VALUE può essere usata per una colonna calcolata (+ indice)Colonne calcolate con JSON_VALUE possono:
Essere nella chiaveEssere nell’INCLUDE
#sqlsatParma#sqlsat462November 28°, 2015
Indicizzazione – esempioJSON_VALUE + Colonne calcolateCREATE TABLE SalesOrderRecord (
Id int PRIMARY KEY IDENTITY,OrderNumber NVARCHAR(25) NOT NULL,OrderDate DATETIME NOT NULL,JOrderDetails NVARCHAR(4000),Quantity AS CAST(JSON_VALUE(JOrderDetails, '$.Order.Qty') AS
int),Price AS JSON_VALUE(JOrderDetails, '$.Order.Price')
)
CREATE INDEX idxJson ON SalesOrderRecord(Quantity) INCLUDE (Price);
#sqlsatParma#sqlsat462November 28°, 2015
Limitazioni FOR JSONSupporto tipi
No CLR (Tranne alcuni come HIERARCHYID)Conversione con Parser integrato
IstruzioniNo SELECT INTO
GeneraliServono alias sempre per valori senza nomeTabella per parsing corretto (FOR JSON AUTO)
#sqlsatParma#sqlsat462November 28°, 2015
FORMATTARE ED ESPORTARE JSON DA SQL SERVER
DEMO
Operazioni non consentite
#sqlsatParma#sqlsat462November 28°, 2015
ConclusioniRiduzione gap nei confronti di competitor (PostgreSQL)Parser integrato ottimizzato (non preferire CLR custom)Pochissimo t-sql aggiuntivo (parametri su funzioni)Funzionalità in V1, molto giovaneIndicizzazione futura? Struttura dedicata su storage?Preferire comunque, per le logiche, l’applicazione
#sqlsatParma#sqlsat462November 28°, 2015
RisorseFOR JSON PATH: https://msdn.microsoft.com/en-us/library/dn921877.aspxFOR JSON AUTO: https://msdn.microsoft.com/en-us/library/dn921883.aspxINCLUDE_NULL_VALUES: https://msdn.microsoft.com/en-us/library/dn921878.aspxROOT: https://msdn.microsoft.com/en-us/library/dn921894.aspxPOST Jovan Popovic: http://blogs.msdn.com/b/jocapc/archive/2015/05/16/json-support-in-sql-server-2016.aspxPOST Aaron Bertrand: http://blogs.sqlsentry.com/aaronbertrand/sql-server-2016-json-support/JSON Online Viewer: http://jsonviewer.stack.hu/JSON Online Query Tool: http://www.jsonquerytool.com/JSON Online Tool: https://www.jsonselect.com/