Ако имате JSON документ, който трябва да вмъкнете в таблица в база данни на SQL Server, OPENJSON()
функцията може да е точно това, от което се нуждаете.
OPENJSON()
е функция с таблично значение, която връща JSON в табличен формат. Тоест, той преобразува вашия JSON в табличен набор от резултати, състоящ се от редове и колони. Следователно ви позволява да го вмъкнете в таблица.
Пример 1 – ИЗБЕРЕТЕ В
В този пример използваме SELECT * INTO
за да създадете нова таблица и да вмъкнете съдържанието на 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
);
Първо декларирах променлива и поставих JSON в нея. След това използвах SELECT * INTO
изявление, за да вмъкнете съдържанието му.
Въпреки това ще забележите, че използвах клауза WITH, за да дефинирам схема. По същество това, което правя тук, е да създавам свои собствени имена на колони и съответните им типове данни, след което да съпоставям всеки JSON ключ с колона.
На последния ред използвам AS JSON
за да укажете, че съдържанието на тази колона е JSON обект или масив.
Това ще стане ясно, когато избера съдържанието на таблицата.
Нека го направим.
SELECT * FROM JsonCats1;
Резултат:
+---------+-----------+--------+------------------------------------------------------+ | 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" } | +---------+-----------+--------+------------------------------------------------------+
Така че можем да видим, че всяка от първите три колони съдържа различна стойност от документа JSON, а последната колона съдържа действителния JSON за всеки елемент от масива.
Можем също да използваме sys.column
изглед на системния каталог проверете имената и типовете на колоните на таблицата.
SELECT
name AS [Column],
TYPE_NAME(system_type_id) AS [Type],
max_length
FROM sys.columns
WHERE OBJECT_ID('JsonCats2') = object_id;
Резултат:
+----------+----------+--------------+ | Column | Type | max_length | |----------+----------+--------------| | Cat Id | int | 4 | | Cat Name | varchar | 60 | | Sex | varchar | 6 | | Cats | nvarchar | -1 | +----------+----------+--------------+
Отново, точно както го посочихме.
Обърнете внимание, че sys.columns
винаги връща max_length
от -1
когато типът данни на колоната е varchar(max) , nvarchar(max) ,варбинарна(макс.) , или xml . Посочихме nvarchar(max) и така стойността на -1
е точно както се очаква.
Също така имайте предвид, че когато използвате AS JSON
(както направихме в четвъртата колона), трябва да направите тази колона nvarchar(max) .
Пример 2 – INSERT INTO
Ето същия пример, освен че този път вмъкваме JSON в таблица, която вече съществува.
Следователно, първото нещо, което трябва да направим, е да създадем таблицата:
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
След като го създадохме, можем да продължим и да вмъкнем съдържанието на нашия 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" }
]
}
}';
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
);
Единствената разлика между този и предишния пример е, че замених следния бит:
SELECT * INTO JsonCats1
С това:
INSERT INTO JsonCats2
SELECT *
Така че, избирането на съдържанието на таблицата ще доведе до същия резултат като предишния пример.
SELECT * FROM JsonCats2;
Резултат:
+---------+-----------+--------+------------------------------------------------------+ | 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" } | +---------+-----------+--------+------------------------------------------------------+
Пример 3 – Използване на схемата по подразбиране
В предишните примери дефинирах моя собствена схема. Тоест посочих имената на колоните за таблиците и посочих действителните типове данни на тези колони.
Ако не го бях направил, OPENJSON()
би използвал схемата по подразбиране. Схемата по подразбиране се състои от три колони; ключ ,стойност , и тип .
Ето пример за използване на схемата по подразбиране при вмъкване на 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 JsonCats3
FROM OPENJSON(@json, '$.pets.cats');
Така че единствената разлика между този и първия пример е, че премахнах целия WITH
клауза. Това е битът, който дефинира схемата в предишните два примера.
Сега нека проверим съдържанието на таблицата.
SELECT * FROM JsonCats3;
Резултат:
+-------+------------------------------------------------------+--------+ | 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 | +-------+------------------------------------------------------+--------+
Тази таблица съдържа трите колони, както е споменато. Стойната колона съдържа всеки елемент от масива.
Пример 4 – Използвайте 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 JsonCats4
FROM OPENJSON(@json, '$.pets.cats')
WITH (
id int,
name varchar(60),
sex varchar(6)
);
Все още дефинираме нашата собствена схема, защото използваме WITH
клауза. Но ще забележите, че не съпоставям имената на колоните с никакъв JSON път. Това е така, защото използвам действителните имена на JSON ключовете.
Когато направите това, OPENJSON()
е достатъчно умен, за да съпостави имената на колоните ви с JSON ключовете.
Да видим какво има в таблицата.
SELECT * FROM JsonCats4;
Резултат:
+------+-----------+--------+ | id | name | sex | |------+-----------+--------| | 1 | Fluffy | Female | | 2 | Long Tail | Female | | 3 | Scratch | Male | +------+-----------+--------+
Така данните са били вмъкнати в таблицата, точно както в първите два примера, но този път имената на колоните са взети от JSON документа.
Пример 5 – Посочете по-малко колони
Не е необходимо да включвате всички стойности от JSON документа, ако не се нуждаете от всички. Можете да посочите само тези, от които се нуждаете.
Можете да направите това, като посочите колоните в SELECT
списък.
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;
Резултат:
+------+-----------+ | id | name | |------+-----------| | 1 | Fluffy | | 2 | Long Tail | | 3 | Scratch | +------+-----------+
Друг начин да го направите е да премахнете съответната колона/и от WITH
клауза.
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;
Резултат:
+------+-----------+ | id | name | |------+-----------| | 1 | Fluffy | | 2 | Long Tail | | 3 | Scratch | +------+-----------+
Въпреки това вероятно е по-добре да направите и двете.
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;
Резултат:
+------+-----------+ | id | name | |------+-----------| | 1 | Fluffy | | 2 | Long Tail | | 3 | Scratch | +------+-----------+
Пример 6 – Посочете по-малко редове
Можете също да използвате нормален T-SQL синтаксис за филтриране на редовете, така че само някои записи да се вмъкват в таблицата.
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;
Резултат:
+------+-----------+ | id | name | |------+-----------| | 1 | Fluffy | | 2 | Long Tail | +------+-----------+
В този случай използвах WHERE
клауза за вмъкване само на редовете, които ме интересуват.
Импортиране на JSON от файл
Можете да използвате OPENJSON()
във връзка с OPENROWSET()
функция за импортиране на JSON файл в таблица.
Това ви позволява да качите данните от JSON файл на локално устройство или мрежово устройство. Това ви спестява от необходимостта да копирате и поставяте съдържанието на документа във вашия SQL код. Това може да бъде особено полезно при работа с големи JSON документи.