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.