Hvis du har et JSON-dokument, er der flere måder, du kan gå for at få det ind i SQL Server.
Hvis det er et lille dokument, kan du kopiere og indsætte dets indhold. Hvis det er et større dokument (eller endda et lille), vil du måske importere hele filen.
Denne artikel præsenterer et eksempel på import af en JSON-fil til en SQL Server-database.
Valg af indholdet af JSON-filen
T-SQL inkluderer OPENROWSET()
funktion, der kan læse data fra enhver fil på det lokale drev eller netværk og returnere det som et rækkesæt. For at gøre det skal du udføre denne funktion med BULK
mulighed.
Selvom denne artikel er skrevet specifikt til at importere JSON-filen til en tabel, kan du også bruge OPENROWSET()
at læse fra en datafil uden nødvendigvis at indlæse den i en tabel.
Dette giver dig mulighed for at tjekke dataene først, før de indlæses i tabellen.
Her er et eksempel på valg af indholdet af en JSON-fil.
SELECT BulkColumn FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB
) AS [Json];
Resultat:
+--------------+| BulkColumn ||--------------|| { "pets" :{ "cats" :[ { "id" :1, "name" :"Fluffy", "sex" :"Kvinde" }, { "id" :2, "name" :"Long Tail" , "sex" :"Kvinde" }, { "id" :3, "name" :"Scratch", "sex" :"Han" } ], "hunde" :[ { "id" :1, "name" :"Fetch", "sex" :"Mand" }, { "id" :2, "name" :"Fluffy", "sex" :"Mand" }, { "id" :3, "name" :" Wag", "sex" :"Kvinde" } ] }} |+--------+
I dette tilfælde er filsystemet Linux, og derfor bruges Linux-stikonventionerne, når man angiver, hvilken fil der skal uploades.
Hvis du er på Windows, ser din filsti måske mere ud som denne:
SELECT BulkColumn FROM OPENROWSET (
BULK 'D:\data\pets.json',
SINGLE_CLOB
) AS [Json];
Under alle omstændigheder kan vi se indholdet af JSON-filen ovenfor. Lad os nu indlæse det i en tabel.
Indlæs det i en tabel
Vi kan ændre den tidligere sætning, så filens indhold importeres direkte ind i en tabel.
-- Import it directly into the table
SELECT BulkColumn INTO ImportedJson FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB
) AS [Json];
-- Select the contents of the table
SELECT * FROM ImportedJson;
Resultat:
+--------------+| BulkColumn ||--------------|| { "pets" :{ "cats" :[ { "id" :1, "name" :"Fluffy", "sex" :"Kvinde" }, { "id" :2, "name" :"Long Tail" , "sex" :"Kvinde" }, { "id" :3, "name" :"Scratch", "sex" :"Han" } ], "hunde" :[ { "id" :1, "name" :"Fetch", "sex" :"Mand" }, { "id" :2, "name" :"Fluffy", "sex" :"Mand" }, { "id" :3, "name" :" Wag", "sex" :"Kvinde" } ] }} |+--------+
Hvis du gør det, oprettes tabellen og indsætter JSON.
Bemærk, at når du bruger OPENROWSET()
med BULK
mulighed, skal du også angive et korrelationsnavn (også kendt som en intervalvariabel eller alias) i FROM
klausul.
Hvis du ikke angiver et korrelationsnavn, får du en fejl.
I mit eksempel brugte jeg Json
som korrelationsnavnet, men vælg gerne dit eget.
Parser JSON i rækker og kolonner
Det er her, tingene bliver spændende. Ikke alene kan vi uploade indholdet af en fil og importere den til en tabelkolonne, vi kan også adskille dens indhold på tværs af flere rækker og kolonner.
OPENJSON()
er en funktion med tabelværdi, der konverterer JSON-dokumenter til et tabelformat.
Derfor kan vi bruge OPENJSON()
at konvertere indholdet af vores JSON-fil til tabelformat, og indsætte det i en tabel eller flere tabeller, hvis det er målet.
Men igen, vi kan tjekke vores data, før vi indsætter dem i nogen tabeller.
-- Select the cats
SELECT Cats.* FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB) AS [Json]
CROSS APPLY OPENJSON ( BulkColumn, '$.pets.cats' )
WITH (
CatId int '$.id',
CatName varchar(60) '$.name',
Sex varchar(6) '$.sex'
) AS [Cats]
-- Select the dogs
SELECT Dogs.* FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB) AS [Json]
CROSS APPLY OPENJSON ( BulkColumn, '$.pets.dogs' )
WITH (
DogId int '$.id',
DogName varchar(60) '$.name',
Sex varchar(6) '$.sex'
) AS [Dogs]
Resultat:
+--------+-----------+--------+| CatId | Kattenavn | Køn ||--------+-----------+--------|| 1 | Fluffy | Kvinde || 2 | Lang hale | Kvinde || 3 | Ridse | Mand |+--------+------------+--------+(3 rækker påvirket)+--------+ ----------+--------+| DogId | Hundenavn | Køn ||--------+-----------+--------|| 1 | Hent | Mand || 2 | Fluffy | Mand || 3 | Wag | Kvinde |+--------+-----------+--------+(3 rækker påvirket)
Sådan vil det se ud, når det først er indsat i to tabeller.
For at indsætte det i tabellerne er det eneste, vi skal gøre, at tilføje INTO TableName
mellem SELECT
del og FROM
(hvor TableName
er navnet på den tabel, vi vil oprette).
-- Insert cats into a table
SELECT Cats.* INTO ImportedCats
FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB) AS [Json]
CROSS APPLY OPENJSON ( BulkColumn, '$.pets.cats' )
WITH (
CatId int '$.id',
CatName varchar(60) '$.name',
Sex varchar(6) '$.sex'
) AS [Cats]
-- Insert dogs into a table
SELECT Dogs.* INTO ImportedDogs
FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB) AS [Json]
CROSS APPLY OPENJSON ( BulkColumn, '$.pets.dogs' )
WITH (
DogId int '$.id',
DogName varchar(60) '$.name',
Sex varchar(6) '$.sex'
) AS [Dogs]
-- Select the results from both tables
SELECT * FROM ImportedCats
SELECT * FROM ImportedDogs
Resultat:
+--------+-----------+--------+| CatId | Kattenavn | Køn ||--------+-----------+--------|| 1 | Fluffy | Kvinde || 2 | Lang hale | Kvinde || 3 | Ridse | Mand |+--------+------------+--------+(3 rækker påvirket)+--------+ ----------+--------+| DogId | Hundenavn | Køn ||--------+-----------+--------|| 1 | Hent | Mand || 2 | Fluffy | Mand || 3 | Wag | Kvinde |+--------+-----------+--------+(3 rækker påvirket)
Disse tabeller blev oprettet ved hjælp af de kolonnedefinitioner, vi leverede i WITH
klausul.
Hver JSON-nøgle er knyttet til et kolonnenavn efter vores valg.
Du kan også basere dine kolonnenavne ud fra nøglenavnene i JSON-filen. Hvis du gør det, behøver du ikke at kortlægge dem med en sti, som OPENJSON()
vil automatisk matche dem med JSON-nøglenavnene.
For eksempel i stedet for at bruge følgende WITH-sætning:
WITH (
DogId int '$.id',
DogName varchar(60) '$.name',
Sex varchar(6) '$.sex'
) AS [Dogs]
Du kan bruge dette:
WITH (
id int,
name varchar(60),
sex varchar(6)
) AS [Dogs]
Indlæs JSON i en variabel
En anden måde at gøre det på ville være at indlæse den uploadede JSON i en variabel og derefter overføre denne variabel til OPENJSON()
funktion.
-- Declare variable
DECLARE @json nvarchar(max);
-- Upload JSON data into that variable
SELECT @json = BulkColumn FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB
) AS [Json];
-- Select the cats from that variable
SELECT * FROM OPENJSON(@json, '$.pets.cats')
WITH (
CatId int '$.id',
CatName varchar(60) '$.name',
Sex varchar(6) '$.sex'
);
-- Select the dogs from that variable
SELECT * FROM OPENJSON(@json, '$.pets.dogs')
WITH (
DogId int '$.id',
DogName varchar(60) '$.name',
Sex varchar(6) '$.sex'
);
Resultat:
+--------+-----------+--------+| CatId | Kattenavn | Køn ||--------+-----------+--------|| 1 | Fluffy | Kvinde || 2 | Lang hale | Kvinde || 3 | Ridse | Mand |+--------+------------+--------+(3 rækker påvirket)+--------+ ----------+--------+| DogId | Hundenavn | Køn ||--------+-----------+--------|| 1 | Hent | Mand || 2 | Fluffy | Mand || 3 | Wag | Kvinde |+--------+-----------+--------+(3 rækker påvirket)
Igen, for at indsætte dette i en tabel, ville vi tilføje INTO TableName
efter SELECT
del (hvor TableName
er navnet på den tabel, du vil oprette).
Indlæs et helt underobjekt i en kolonne
Hvis du ønskede, at hele underobjekter skulle ligge i deres egen kolonne, kan du bruge AS JSON
mulighed for WITH
klausul.
For eksempel, i stedet for at have hver kat og hund fordelt på tre kolonner, kan hele deres JSON-fragment fylde én kolonne. Hvert dyr vil stadig have deres egen række.
Her er et eksempel på, hvad jeg mener.
SELECT Cats.* FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB) AS [Json]
CROSS APPLY OPENJSON ( BulkColumn, '$.pets.cats' )
WITH (
Cats nvarchar(max) '$' AS JSON
) AS [Cats]
SELECT Dogs.* FROM OPENROWSET (
BULK '/var/opt/mssql/bak/pets.json',
SINGLE_CLOB) AS [Json]
CROSS APPLY OPENJSON ( BulkColumn, '$.pets.dogs' )
WITH (
Dogs nvarchar(max) '$' AS JSON
) AS [Dogs]
Resultat:
+---------------------------------------------- --------+| Katte ||------------------------------------------------------ -------|| { "id" :1, "name" :"Fluffy", "sex" :"Kvinde" } || { "id" :2, "name" :"Lang hale", "sex" :"Kvinde" } || { "id" :3, "name" :"Scratch", "sex" :"Mand" } |+-------------------------------- ------------------------------+(3 rækker påvirket)+-------- -----------------------------------+| Hunde ||------------------------------------------------------ --|| { "id" :1, "name" :"Hent", "sex" :"Mand" } || { "id" :2, "name" :"Fluffy", "sex" :"Mand" } || { "id" :3, "name" :"Wag", "sex" :"Kvinde" } |+-------------------------------- ------------------------+(3 rækker påvirket)