Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak wstawić JSON do tabeli w SQL Server

Jeśli masz dokument JSON, który musisz wstawić do tabeli w bazie danych SQL Server, OPENJSON() funkcja może być właśnie tym, czego potrzebujesz.

OPENJSON() to funkcja zwracająca tabelę, która zwraca JSON w formacie tabelarycznym. Oznacza to, że konwertuje twój JSON na tabelaryczny zestaw wyników składający się z wierszy i kolumn. Dlatego umożliwia wstawienie go do tabeli.

Przykład 1 – WYBIERZ DO

W tym przykładzie używamy SELECT * INTO aby utworzyć nową tabelę i wstawić do niej zawartość dokumentu JSON.

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

Najpierw zadeklarowałem zmienną i umieściłem w niej JSON. Następnie użyłem SELECT * INTO oświadczenie, aby wstawić jego zawartość.

Zauważysz jednak, że do zdefiniowania schematu użyłem klauzuli WITH. Zasadniczo to, co tutaj robię, to tworzenie własnych nazw kolumn i odpowiadających im typów danych, a następnie mapowanie każdego klucza JSON za pomocą kolumny.

W ostatnim wierszu używam AS JSON aby określić, że zawartość tej kolumny jest obiektem lub tablicą JSON.

Stanie się to jasne, gdy wybiorę zawartość tabeli.

Zróbmy to.

SELECT * FROM JsonCats1;

Wynik:

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

Widzimy więc, że każda z pierwszych trzech kolumn zawiera inną wartość niż w dokumencie JSON, a ostatnia kolumna zawiera rzeczywisty JSON dla każdego elementu tablicy.

Możemy również użyć sys.column widok katalogu systemowego sprawdź nazwy i typy kolumn tabeli.

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

Wynik:

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

Ponownie, dokładnie tak, jak to określiliśmy.

Zauważ, że sys.columns zawsze zwraca max_length z -1 gdy typ danych kolumny to varchar(max) , nvarchar(maks.) , zmienna (maks.) lub xml . Określiliśmy nvarchar(max) a więc wartość -1 jest dokładnie taki, jak oczekiwano.

Pamiętaj też, że gdy używasz AS JSON (tak jak zrobiliśmy w czwartej kolumnie), musisz ustawić tę kolumnę jako nvarchar(max) .

Przykład 2 – WSTAW DO

Oto ten sam przykład, ale tym razem wstawiamy JSON do tabeli, która już istnieje.

Dlatego pierwszą rzeczą, którą musimy zrobić, to utworzyć tabelę:

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

Teraz, gdy to stworzyliśmy, możemy śmiało wstawić zawartość naszego dokumentu JSON do tej tabeli.

Tak:

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

Jedyna różnica między tym a poprzednim przykładem polega na tym, że zastąpiłem następujący bit:

SELECT * INTO JsonCats1

Dzięki temu:

INSERT INTO JsonCats2
SELECT * 

Tak więc wybranie zawartości tabeli da taki sam wynik, jak w poprzednim przykładzie.

SELECT * FROM JsonCats2;

Wynik:

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

Przykład 3 – Używanie domyślnego schematu

W poprzednich przykładach zdefiniowałem własny schemat. Oznacza to, że określiłem nazwy kolumn dla tabel i określiłem rzeczywiste typy danych tych kolumn.

Gdybym tego nie zrobił, OPENJSON() użyłby domyślnego schematu. Domyślny schemat składa się z trzech kolumn; klucz , wartość i wpisz .

Oto przykład użycia domyślnego schematu podczas wstawiania JSON do tabeli.

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

Więc jedyną różnicą między tym a pierwszym przykładem jest to, że usunąłem cały WITH klauzula. To jest fragment, który zdefiniował schemat w poprzednich dwóch przykładach.

Sprawdźmy teraz zawartość tabeli.

SELECT * FROM JsonCats3;

Wynik:

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

Ta tabela zawiera trzy wspomniane kolumny. Kolumna wartości zawiera każdy element tablicy.

Przykład 4 – Użyj kluczy JSON jako nagłówków kolumn

Ten przykład jest trochę skrzyżowaniem dwóch poprzednich przykładów.

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

Wciąż definiujemy własny schemat, ponieważ używamy WITH klauzula. Zauważysz jednak, że nie mapuję nazw kolumn na żadną ścieżkę JSON. Dzieje się tak, ponieważ używam rzeczywistych nazw kluczy JSON.

Kiedy to zrobisz, OPENJSON() jest wystarczająco sprytny, aby dopasować nazwy kolumn do kluczy JSON.

Zobaczmy, co jest w tabeli.

SELECT * FROM JsonCats4;

Wynik:

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

Tak więc dane zostały wstawione do tabeli, tak jak w pierwszych dwóch przykładach, ale tym razem nazwy kolumn zostały zaczerpnięte z dokumentu JSON.

Przykład 5 – Określ mniej kolumn

Nie musisz uwzględniać wszystkich wartości z dokumentu JSON, jeśli nie potrzebujesz ich wszystkich. Możesz określić tylko te, których potrzebujesz.

Możesz to zrobić, określając kolumny w SELECT lista.

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;

Wynik:

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

Innym sposobem na to jest usunięcie odpowiednich kolumn z WITH klauzula.

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;

Wynik:

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

Chociaż prawdopodobnie lepiej jest zrobić jedno i drugie.

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;

Wynik:

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

Przykład 6 – Określ mniej wierszy

Do filtrowania wierszy można również użyć normalnej składni T-SQL, tak aby do tabeli wstawić tylko niektóre rekordy.

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;

Wynik:

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

W tym przypadku użyłem WHERE klauzula, aby wstawić tylko te wiersze, które mnie interesują.

Importuj JSON z pliku

Możesz użyć OPENJSON() w połączeniu z OPENROWSET() funkcja importowania pliku JSON do tabeli.

Dzięki temu możesz przesłać dane z pliku JSON na dysk lokalny lub dysk sieciowy. Dzięki temu nie musisz kopiować i wklejać zawartości dokumentu do kodu SQL. Może to być szczególnie korzystne podczas pracy z dużymi dokumentami JSON.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Node.js i Microsoft SQL Server

  2. LEN() vs DATALENGTH() w SQL Server

  3. Jak Operator w Entity Framework?

  4. Zachowanie planu zapytań dotyczących tabel danych czasowych programu SQL Server 2016

  5. Jak zaktualizować z SELECT w SQL Server?