Om du har ett JSON-dokument finns det flera sätt att få in det i SQL Server.
Om det är ett litet dokument kan du kopiera och klistra in dess innehåll. Om det är ett större dokument (eller till och med ett litet), kanske du vill importera hela filen.
Den här artikeln presenterar ett exempel på import av en JSON-fil till en SQL Server-databas.
Välja innehållet i JSON-filen
T-SQL innehåller OPENROWSET()
funktion, som kan läsa data från vilken fil som helst på den lokala enheten eller nätverket och returnera den som en raduppsättning. För att göra det, kör den här funktionen med BULK
alternativ.
Även om den här artikeln skrevs specifikt för att importera JSON-filen till en tabell, kan du också använda OPENROWSET()
att läsa från en datafil utan att nödvändigtvis ladda den i en tabell.
Detta gör att du kan kontrollera data först innan du laddar in den i tabellen.
Här är ett exempel på hur du väljer innehållet i 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" : "Female" }, { "id" : 2, "name" : "Long Tail", "sex" : "Female" }, { "id" : 3, "name" : "Scratch", "sex" : "Male" } ], "dogs" : [ { "id" : 1, "name" : "Fetch", "sex" : "Male" }, { "id" : 2, "name" : "Fluffy", "sex" : "Male" }, { "id" : 3, "name" : "Wag", "sex" : "Female" } ] } } | +--------------+
I det här fallet är filsystemet Linux, och därför används Linux-sökvägskonventionerna när man anger vilken fil som ska laddas upp.
Om du använder Windows kan din filsökväg se ut mer så här:
SELECT BulkColumn FROM OPENROWSET (
BULK 'D:\data\pets.json',
SINGLE_CLOB
) AS [Json];
Hur som helst, vi kan se innehållet i JSON-filen ovan. Låt oss nu ladda det i en tabell.
Läs in den i en tabell
Vi kan modifiera det tidigare uttalandet så att filens innehåll importeras rakt in i en tabell.
-- 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" : "Female" }, { "id" : 2, "name" : "Long Tail", "sex" : "Female" }, { "id" : 3, "name" : "Scratch", "sex" : "Male" } ], "dogs" : [ { "id" : 1, "name" : "Fetch", "sex" : "Male" }, { "id" : 2, "name" : "Fluffy", "sex" : "Male" }, { "id" : 3, "name" : "Wag", "sex" : "Female" } ] } } | +--------------+
Om du gör det skapas tabellen och infogar JSON.
Observera att när du använder OPENROWSET()
med BULK
alternativet måste du också ange ett korrelationsnamn (även känt som en intervallvariabel eller alias) i FROM
klausul.
Om du inte anger ett korrelationsnamn får du ett felmeddelande.
I mitt exempel använde jag Json
som korrelationsnamn, men välj gärna ditt eget.
Parsera JSON i rader och kolumner
Det är här det blir spännande. Vi kan inte bara ladda upp innehållet i en fil och importera den till en tabellkolumn, vi kan också separera dess innehåll över flera rader och kolumner.
OPENJSON()
är en tabellvärderad funktion som konverterar JSON-dokument till ett tabellformat.
Därför kan vi använda OPENJSON()
att konvertera innehållet i vår JSON-fil till tabellformat och infoga det i en tabell eller flera tabeller om det är målet.
Men återigen, vi kan kontrollera vår data innan vi infogar den i några 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 | CatName | Sex | |---------+-----------+--------| | 1 | Fluffy | Female | | 2 | Long Tail | Female | | 3 | Scratch | Male | +---------+-----------+--------+ (3 rows affected) +---------+-----------+--------+ | DogId | DogName | Sex | |---------+-----------+--------| | 1 | Fetch | Male | | 2 | Fluffy | Male | | 3 | Wag | Female | +---------+-----------+--------+ (3 rows affected)
Det är precis så det kommer att se ut när det har infogats i två tabeller.
För att infoga det i tabellerna behöver vi bara lägga till INTO TableName
mellan SELECT
del och FROM
(där TableName
är namnet på tabellen vi vill skapa).
-- 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 | CatName | Sex | |---------+-----------+--------| | 1 | Fluffy | Female | | 2 | Long Tail | Female | | 3 | Scratch | Male | +---------+-----------+--------+ (3 rows affected) +---------+-----------+--------+ | DogId | DogName | Sex | |---------+-----------+--------| | 1 | Fetch | Male | | 2 | Fluffy | Male | | 3 | Wag | Female | +---------+-----------+--------+ (3 rows affected)
Dessa tabeller skapades med hjälp av kolumndefinitionerna som vi angav i WITH
klausul.
Varje JSON-nyckel mappas till ett kolumnnamn som vi väljer.
Du kan också basera dina kolumnnamn på nyckelnamnen i JSON-filen. Om du gör det behöver du inte mappa dem med en sökväg, som OPENJSON()
kommer automatiskt att matcha dem med JSON-nyckelnamnen.
Till exempel istället för att använda följande WITH-sats:
WITH (
DogId int '$.id',
DogName varchar(60) '$.name',
Sex varchar(6) '$.sex'
) AS [Dogs]
Du kan använda detta:
WITH (
id int,
name varchar(60),
sex varchar(6)
) AS [Dogs]
Läs in JSON i en variabel
Ett annat sätt att göra det skulle vara att ladda den uppladdade JSON-filen till en variabel och sedan skicka den variabeln till 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 | CatName | Sex | |---------+-----------+--------| | 1 | Fluffy | Female | | 2 | Long Tail | Female | | 3 | Scratch | Male | +---------+-----------+--------+ (3 rows affected) +---------+-----------+--------+ | DogId | DogName | Sex | |---------+-----------+--------| | 1 | Fetch | Male | | 2 | Fluffy | Male | | 3 | Wag | Female | +---------+-----------+--------+ (3 rows affected)
Återigen, för att infoga detta i en tabell, skulle vi lägga till INTO TableName
efter SELECT
del (där TableName
är namnet på tabellen du vill skapa).
Läs in ett helt underobjekt i en kolumn
Om du vill att hela underobjekt ska finnas i sin egen kolumn kan du använda AS JSON
alternativet WITH
klausul.
Till exempel, istället för att ha varje katt och hund fördelade över tre kolumner, kan hela deras JSON-fragment ta upp en kolumn. Varje djur kommer fortfarande att ha sin egen rad.
Här är ett exempel på vad jag menar.
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:
+------------------------------------------------------+ | Cats | |------------------------------------------------------| | { "id" : 1, "name" : "Fluffy", "sex" : "Female" } | | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } | | { "id" : 3, "name" : "Scratch", "sex" : "Male" } | +------------------------------------------------------+ (3 rows affected) +-------------------------------------------------+ | Dogs | |-------------------------------------------------| | { "id" : 1, "name" : "Fetch", "sex" : "Male" } | | { "id" : 2, "name" : "Fluffy", "sex" : "Male" } | | { "id" : 3, "name" : "Wag", "sex" : "Female" } | +-------------------------------------------------+ (3 rows affected)