sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan indsætter du JSON i en tabel i SQL Server

Hvis du har et JSON-dokument, som du skal indsætte i en tabel i en SQL Server-database, vil OPENJSON() funktion kunne være lige, hvad du har brug for.

OPENJSON() er en funktion med tabelværdi, der returnerer JSON i tabelformat. Det vil sige, at den konverterer din JSON til et tabelresultatsæt bestående af rækker og kolonner. Derfor giver det dig mulighed for at indsætte det i en tabel.

Eksempel 1 – VÆLG INTO

I dette eksempel bruger vi SELECT * INTO for at oprette en ny tabel og indsætte indholdet af JSON-dokumentet i den.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT * INTO JsonCats1
FROM OPENJSON(@json, '$.pets.cats')
WITH  (
        CatId     int             '$.id',  
        CatName   varchar(60)     '$.name', 
        Sex       varchar(6)      '$.sex', 
        Cats      nvarchar(max)   '$' AS JSON   
    );

Jeg erklærede først en variabel og satte JSON ind i den. Så brugte jeg en SELECT * INTO erklæring for at indsætte dens indhold.

Du vil dog bemærke, at jeg brugte en WITH-klausul til at definere et skema. Grundlæggende er det, jeg gør her, at oprette mine egne kolonnenavne og deres respektive datatyper og derefter kortlægge hver JSON-nøgle med en kolonne.

På den sidste linje bruger jeg AS JSON for at angive, at indholdet af den kolonne er et JSON-objekt eller et array.

Dette bliver tydeligt, når jeg vælger indholdet af tabellen.

Lad os gøre det.

SELECT * FROM JsonCats1;

Resultat:

+---------+-----------+--------+------------------------------------------------------+
| CatId   | CatName   | Sex    | Cats                                                 |
|---------+-----------+--------+------------------------------------------------------|
| 1       | Fluffy    | Female | { "id" : 1, "name" : "Fluffy", "sex" : "Female" }    |
| 2       | Long Tail | Female | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } |
| 3       | Scratch   | Male   | { "id" : 3, "name" : "Scratch", "sex" : "Male" }     |
+---------+-----------+--------+------------------------------------------------------+

Så vi kan se, at de første tre kolonner hver indeholder en anden værdi end JSON-dokumentet, og den sidste kolonne indeholder den faktiske JSON for hvert array-element.

Vi kan også bruge sys.column systemkatalogvisning kontroller tabellens kolonnenavne og -typer.

SELECT
    name AS [Column],
    TYPE_NAME(system_type_id) AS [Type],
    max_length
FROM sys.columns 
WHERE OBJECT_ID('JsonCats2') = object_id;

Resultat:

+----------+----------+--------------+
| Column   | Type     | max_length   |
|----------+----------+--------------|
| Cat Id   | int      | 4            |
| Cat Name | varchar  | 60           |
| Sex      | varchar  | 6            |
| Cats     | nvarchar | -1           |
+----------+----------+--------------+

Igen, præcis hvordan vi havde specificeret det.

Bemærk, at sys.columns returnerer altid en max_length af -1 når kolonnedatatypen er varchar(max) , nvarchar(max) , varbinary(max) eller xml . Vi specificerede nvarchar(max) og så værdien af ​​-1 er nøjagtigt som forventet.

Bemærk også, at når du bruger AS JSON (som vi gjorde i den fjerde kolonne), skal du gøre den kolonne til en nvarchar(max) .

Eksempel 2 – INDSÆT I

Her er det samme eksempel, bortset fra at denne gang indsætter vi JSON i en tabel, der allerede eksisterer.

Derfor er det første, vi skal gøre, at oprette tabellen:

CREATE TABLE [dbo].[JsonCats2](
	[CatId] [int] NULL,
	[CatName] [varchar](60) NULL,
	[Sex] [varchar](6) NULL,
	[Cats] [nvarchar](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Nu hvor vi har oprettet det, kan vi gå videre og indsætte indholdet af vores JSON-dokument i den tabel.

Sådan:

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

INSERT INTO JsonCats2
SELECT * 
FROM OPENJSON(@json, '$.pets.cats')
WITH  (
        CatId     int             '$.id',  
        CatName   varchar(60)     '$.name', 
        Sex       varchar(6)      '$.sex', 
        Cats      nvarchar(max)   '$' AS JSON   
    );

Den eneste forskel mellem dette og det forrige eksempel er, at jeg erstattede følgende bit:

SELECT * INTO JsonCats1

Med denne:

INSERT INTO JsonCats2
SELECT * 

Så valg af indholdet i tabellen vil give det samme resultat som det foregående eksempel.

SELECT * FROM JsonCats2;

Resultat:

+---------+-----------+--------+------------------------------------------------------+
| CatId   | CatName   | Sex    | Cats                                                 |
|---------+-----------+--------+------------------------------------------------------|
| 1       | Fluffy    | Female | { "id" : 1, "name" : "Fluffy", "sex" : "Female" }    |
| 2       | Long Tail | Female | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } |
| 3       | Scratch   | Male   | { "id" : 3, "name" : "Scratch", "sex" : "Male" }     |
+---------+-----------+--------+------------------------------------------------------+

Eksempel 3 – Brug af standardskemaet

I de foregående eksempler definerede jeg mit eget skema. Det vil sige, jeg specificerede navnene på kolonnerne til tabellerne, og jeg specificerede de faktiske datatyper for disse kolonner.

Hvis jeg ikke havde gjort det, OPENJSON() ville have brugt standardskemaet. Standardskemaet består af tre kolonner; tast , værdi , og skriv .

Her er et eksempel på brug af standardskemaet, når du indsætter JSON i en tabel.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT * INTO JsonCats3
FROM OPENJSON(@json, '$.pets.cats');

Så den eneste forskel mellem dette og det første eksempel er, at jeg fjernede hele WITH klausul. Det er den bit, der definerede skemaet i de to foregående eksempler.

Lad os nu tjekke indholdet af tabellen.

SELECT * FROM JsonCats3;

Resultat:

+-------+------------------------------------------------------+--------+
| key   | value                                                | type   |
|-------+------------------------------------------------------+--------|
| 0     | { "id" : 1, "name" : "Fluffy", "sex" : "Female" }    | 5      |
| 1     | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } | 5      |
| 2     | { "id" : 3, "name" : "Scratch", "sex" : "Male" }     | 5      |
+-------+------------------------------------------------------+--------+

Denne tabel indeholder de tre nævnte kolonner. Værdikolonnen indeholder hvert array-element.

Eksempel 4 – Brug JSON-nøgler som kolonneoverskrifter

Dette eksempel er lidt af en krydsning mellem de to foregående eksempler.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT * INTO JsonCats4
FROM OPENJSON(@json, '$.pets.cats')
WITH (
    id int,
    name varchar(60),
    sex varchar(6)
);

Vi er stadig ved at definere vores eget skema, fordi vi bruger WITH klausul. Men du vil bemærke, at jeg ikke kortlægger kolonnenavnene til nogen JSON-sti. Dette skyldes, at jeg bruger de faktiske navne på JSON-nøglerne.

Når du gør det, OPENJSON() er smart nok til at matche dine kolonnenavne med JSON-nøglerne.

Lad os se, hvad der står i tabellen.

SELECT * FROM JsonCats4;

Resultat:

+------+-----------+--------+
| id   | name      | sex    |
|------+-----------+--------|
| 1    | Fluffy    | Female |
| 2    | Long Tail | Female |
| 3    | Scratch   | Male   |
+------+-----------+--------+

Så dataene er blevet indsat i tabellen, ligesom i de første to eksempler, men denne gang er kolonnenavnene taget fra JSON-dokumentet.

Eksempel 5 – Angiv færre kolonner

Du behøver ikke at inkludere alle værdier fra JSON-dokumentet, hvis du ikke har brug for dem alle. Du kan kun angive dem, du har brug for.

Du kan gøre dette ved at angive kolonnerne i SELECT liste.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT 
    id, 
    name 
INTO JsonCats5a
FROM OPENJSON(@json, '$.pets.cats')
WITH (
    id int,
    name varchar(60),
    sex varchar(6)
);

SELECT * FROM JsonCats5a;

Resultat:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
| 3    | Scratch   |
+------+-----------+

En anden måde at gøre det på er at fjerne de relevante kolonner fra WITH klausul.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT * INTO JsonCats5b
FROM OPENJSON(@json, '$.pets.cats')
WITH (
    id int,
    name varchar(60)
);

SELECT * FROM JsonCats5b;

Resultat:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
| 3    | Scratch   |
+------+-----------+

Selvom det nok er bedre at gøre begge dele.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT 
    id,
    name
INTO JsonCats5c
FROM OPENJSON(@json, '$.pets.cats')
WITH (
    id int,
    name varchar(60)
);

SELECT * FROM JsonCats5c;

Resultat:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
| 3    | Scratch   |
+------+-----------+

Eksempel 6 – Angiv færre rækker

Du kan også bruge normal T-SQL-syntaks til at filtrere rækkerne, så kun nogle poster indsættes i tabellen.

DECLARE @json NVARCHAR(4000) = N'{ 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "name" : "Fetch", "sex" : "Male" },
            { "name" : "Fluffy", "sex" : "Male" },
            { "name" : "Wag", "sex" : "Female" }
        ]
    }
}';

SELECT 
    id,
    name
INTO JsonCats6
FROM OPENJSON(@json, '$.pets.cats')
WITH (
    id int,
    name varchar(60)
)
WHERE id IN (1,2);

SELECT * FROM JsonCats6;

Resultat:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
+------+-----------+

I dette tilfælde brugte jeg en WHERE klausul for kun at indsætte de rækker, som jeg er interesseret i.

Importer JSON fra en fil

Du kan bruge OPENJSON() i forbindelse med OPENROWSET() funktion til at importere en JSON-fil til en tabel.

Dette giver dig mulighed for at uploade data fra en JSON-fil på et lokalt drev eller netværksdrev. Dette sparer dig for at skulle kopiere og indsætte dokumentets indhold i din SQL-kode. Dette kan være særligt fordelagtigt, når du arbejder med store JSON-dokumenter.


  1. Trigger for at håndhæve M-M-forhold

  2. En dedikeret lagret procedure for at få den seneste database-backup-status

  3. 3 måder at returnere alle tabeller UDEN en primær nøgle i SQL Server

  4. Sådan returnerer du måneds- og dagnavne på et andet sprog i MariaDB