Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

So fügen Sie JSON in eine Tabelle in SQL Server ein

Wenn Sie ein JSON-Dokument haben, das Sie in eine Tabelle in einer SQL Server-Datenbank einfügen müssen, wird die Datei OPENJSON() Funktion könnte genau das sein, was Sie brauchen.

OPENJSON() ist eine Tabellenwertfunktion, die JSON im Tabellenformat zurückgibt. Das heißt, es konvertiert Ihr JSON in eine tabellarische Ergebnismenge, die aus Zeilen und Spalten besteht. Daher können Sie es in eine Tabelle einfügen.

Beispiel 1 – AUSWÄHLEN IN

In diesem Beispiel verwenden wir SELECT * INTO um eine neue Tabelle zu erstellen und den Inhalt des JSON-Dokuments darin einzufügen.

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   
    );

Ich habe zuerst eine Variable deklariert und den JSON darin eingefügt. Dann habe ich ein SELECT * INTO verwendet Anweisung, um seinen Inhalt einzufügen.

Sie werden jedoch feststellen, dass ich eine WITH-Klausel verwendet habe, um ein Schema zu definieren. Im Grunde erstelle ich hier meine eigenen Spaltennamen und ihre jeweiligen Datentypen und bilde dann jeden JSON-Schlüssel einer Spalte zu.

In der letzten Zeile verwende ich AS JSON um anzugeben, dass der Inhalt dieser Spalte ein JSON-Objekt oder -Array ist.

Das wird deutlich, wenn ich den Inhalt der Tabelle auswähle.

Machen wir das.

SELECT * FROM JsonCats1;

Ergebnis:

+---------+-----------+--------+------------------------------------------------------+
| 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" }     |
+---------+-----------+--------+------------------------------------------------------+

Wir können also sehen, dass die ersten drei Spalten jeweils einen anderen Wert aus dem JSON-Dokument enthalten und die letzte Spalte den tatsächlichen JSON für jedes Array-Element enthält.

Wir können auch die sys.column verwenden Systemkatalogansicht überprüfen Sie die Spaltennamen und -typen der Tabelle.

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

Ergebnis:

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

Wieder genau so, wie wir es angegeben hatten.

Beachten Sie, dass sys.columns gibt immer eine max_length zurück von -1 wenn der Datentyp der Spalte varchar(max) ist , nvarchar(max) , varbinary(max) , oder xml . Wir haben nvarchar(max) angegeben und damit der Wert von -1 ist genau wie erwartet.

Beachten Sie auch, wenn Sie AS JSON verwenden (wie bei der vierten Spalte) müssen Sie diese Spalte zu einem nvarchar(max) machen .

Beispiel 2 – EINFÜGEN IN

Hier ist das gleiche Beispiel, außer dass wir diesmal den JSON in eine bereits vorhandene Tabelle einfügen.

Daher müssen wir als erstes die Tabelle erstellen:

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

Jetzt, da wir das erstellt haben, können wir fortfahren und den Inhalt unseres JSON-Dokuments in diese Tabelle einfügen.

So:

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   
    );

Der einzige Unterschied zwischen diesem und dem vorherigen Beispiel besteht darin, dass ich das folgende Bit ersetzt habe:

SELECT * INTO JsonCats1

Damit:

INSERT INTO JsonCats2
SELECT * 

Wenn Sie also den Inhalt der Tabelle auswählen, wird dasselbe Ergebnis wie im vorherigen Beispiel erzeugt.

SELECT * FROM JsonCats2;

Ergebnis:

+---------+-----------+--------+------------------------------------------------------+
| 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" }     |
+---------+-----------+--------+------------------------------------------------------+

Beispiel 3 – Verwenden des Standardschemas

In den vorherigen Beispielen habe ich mein eigenes Schema definiert. Das heißt, ich habe die Namen der Spalten für die Tabellen und die tatsächlichen Datentypen dieser Spalten angegeben.

Wenn ich das nicht getan hätte, OPENJSON() hätte das Standardschema verwendet. Das Standardschema besteht aus drei Spalten; Schlüssel , Wert , und tippen .

Hier ist ein Beispiel für die Verwendung des Standardschemas beim Einfügen von JSON in eine Tabelle.

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');

Der einzige Unterschied zwischen diesem und dem ersten Beispiel ist also, dass ich den gesamten WITH entfernt habe Klausel. Das ist das Bit, das das Schema in den beiden vorherigen Beispielen definiert hat.

Lassen Sie uns nun den Inhalt der Tabelle überprüfen.

SELECT * FROM JsonCats3;

Ergebnis:

+-------+------------------------------------------------------+--------+
| 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      |
+-------+------------------------------------------------------+--------+

Diese Tabelle enthält die drei erwähnten Spalten. Die Wertespalte enthält jedes Array-Element.

Beispiel 4 – Verwenden Sie JSON-Schlüssel als Spaltenüberschriften

Dieses Beispiel ist ein bisschen eine Kreuzung zwischen den beiden vorherigen Beispielen.

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)
);

Wir definieren immer noch unser eigenes Schema, weil wir den WITH verwenden Klausel. Aber Sie werden feststellen, dass ich die Spaltennamen keinem JSON-Pfad zuordne. Das liegt daran, dass ich die tatsächlichen Namen der JSON-Schlüssel verwende.

Wenn Sie das tun, OPENJSON() ist intelligent genug, um Ihre Spaltennamen mit den JSON-Schlüsseln abzugleichen.

Mal sehen, was in der Tabelle steht.

SELECT * FROM JsonCats4;

Ergebnis:

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

Die Daten wurden also wie in den ersten beiden Beispielen in die Tabelle eingefügt, aber diesmal wurden die Spaltennamen aus dem JSON-Dokument übernommen.

Beispiel 5 – Geben Sie weniger Spalten an

Sie müssen nicht alle Werte aus dem JSON-Dokument einschließen, wenn Sie sie nicht alle benötigen. Sie können nur diejenigen angeben, die Sie benötigen.

Dies können Sie tun, indem Sie die Spalten im SELECT angeben 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;

Ergebnis:

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

Eine andere Möglichkeit besteht darin, die relevante(n) Spalte(n) aus dem WITH zu entfernen Klausel.

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;

Ergebnis:

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

Obwohl es wahrscheinlich besser ist, beides zu tun.

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;

Ergebnis:

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

Beispiel 6 – Geben Sie weniger Zeilen an

Sie können auch die normale T-SQL-Syntax verwenden, um die Zeilen zu filtern, sodass nur einige Datensätze in die Tabelle eingefügt werden.

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;

Ergebnis:

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

In diesem Fall habe ich ein WHERE verwendet -Klausel, um nur die Zeilen einzufügen, die mich interessieren.

JSON aus einer Datei importieren

Sie können OPENJSON() verwenden in Verbindung mit dem OPENROWSET() Funktion zum Importieren einer JSON-Datei in eine Tabelle.

Dadurch können Sie die Daten aus einer JSON-Datei auf ein lokales Laufwerk oder Netzlaufwerk hochladen. Dies erspart Ihnen das Kopieren und Einfügen des Dokumentinhalts in Ihren SQL-Code. Dies kann besonders nützlich sein, wenn Sie mit großen JSON-Dokumenten arbeiten.