在SQL Server中解析JSON
参考Microsoft提供的示例:在SQL Server中解析JSON,sql,sql-server,json,sql-server-2016,Sql,Sql Server,Json,Sql Server 2016,参考Microsoft提供的示例: DECLARE @json NVARCHAR(MAX) SET @json = N'[ { "id" : 2,"info": { "name": "John", "surname": "Smith" }, "age": 25 }, { "id" : 5,"info": { "name": "Jane", "surname": "Smith" }, "dob": "2005-11-04T12:00:00" } ]'
DECLARE @json NVARCHAR(MAX)
SET @json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "age": 25 },
{ "id" : 5,"info": { "name": "Jane", "surname": "Smith" }, "dob": "2005-11-04T12:00:00" }
]'
SELECT *
FROM OPENJSON(@json)
WITH (id int 'strict $.id',
firstName nvarchar(50) '$.info.name', lastName nvarchar(50) '$.info.surname',
age int, dateOfBirth datetime2 '$.dob')
当JSON数据中包含数组时,例如:
DECLARE @json NVARCHAR(MAX)
SET @json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" },
"Phones": ["123","345","678"] // like here
}
]'
是否有任何方法可以连接解析数据上的数组以获得如下内容:
Id First Name Last Name Phone
2 John Smith 123
2 John Smith 345
2 John Smith 678
DECLARE @json NVARCHAR(MAX)
SET @json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "Phones": ["123","345","678"] },
{ "id" : 3,"info": { "name": "Jane", "surname": "Smith" }, "Phones": ["321","543"] }
]';
WITH CTE AS (
SELECT id, firstName, lastName, phones
FROM OPENJSON(@json)
WITH (
id INT 'strict $.id',
firstName NVARCHAR(50) '$.info.name',
lastName NVARCHAR(50) '$.info.surname',
phones NVARCHAR(MAX) '$.Phones' AS JSON
)
)
SELECT c.id, c.firstName, c.lastName, p.value as phone
FROM CTE c
CROSS APPLY OPENJSON(c.phones) p
SELECT ID, FirstName, LastName, value
FROM OPENJSON(@json)
WITH(ID int '$.id',
FirstName nvarchar(50) '$.info.name',
LastName nvarchar(50) '$.info.surname',
Phones nvarchar(max) '$.Phones' AS Json)
CROSS APPLY OPENJSON(Phones)
OUTER APPLY
是您的朋友。让我们把这两种行混在一起,以便更好地衡量
DECLARE @json NVARCHAR(MAX)
SET @json = N'
[
{
"id": 2,
"info": {
"name": "John",
"surname": "Smith"
},
"age": 25,
"Phones": [
"123",
"345",
"678"
]
},
{
"id": 5,
"info": {
"name": "Jane",
"surname": "Smith"
},
"dob": "2005-11-04T12:00:00"
}
]'
SELECT id, [name], [surname], age, dateOfBirth, number
FROM (
SELECT *
FROM OPENJSON(@json)
WITH (
id INT 'strict $.id',
[name] NVARCHAR(50) '$.info.name',
[surname] NVARCHAR(50) '$.info.surname',
age INT,
dateOfBirth DATETIME2 '$.dob',
Phones NVARCHAR(MAX) AS JSON
)
) AS people
OUTER APPLY OPENJSON(Phones)
WITH (
number NVARCHAR(50) '$'
)
结果:
+----+------+---------+------+-----------------------------+--------+
| id | name | surname | age | dateOfBirth | number |
+----+------+---------+------+-----------------------------+--------+
| 2 | John | Smith | 25 | NULL | 123 |
| 2 | John | Smith | 25 | NULL | 345 |
| 2 | John | Smith | 25 | NULL | 678 |
| 5 | Jane | Smith | NULL | 2005-11-04 12:00:00.0000000 | NULL |
+----+------+---------+------+-----------------------------+--------+
您必须分两次完成:
Id First Name Last Name Phone
2 John Smith 123
2 John Smith 345
2 John Smith 678
DECLARE @json NVARCHAR(MAX)
SET @json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "Phones": ["123","345","678"] },
{ "id" : 3,"info": { "name": "Jane", "surname": "Smith" }, "Phones": ["321","543"] }
]';
WITH CTE AS (
SELECT id, firstName, lastName, phones
FROM OPENJSON(@json)
WITH (
id INT 'strict $.id',
firstName NVARCHAR(50) '$.info.name',
lastName NVARCHAR(50) '$.info.surname',
phones NVARCHAR(MAX) '$.Phones' AS JSON
)
)
SELECT c.id, c.firstName, c.lastName, p.value as phone
FROM CTE c
CROSS APPLY OPENJSON(c.phones) p
SELECT ID, FirstName, LastName, value
FROM OPENJSON(@json)
WITH(ID int '$.id',
FirstName nvarchar(50) '$.info.name',
LastName nvarchar(50) '$.info.surname',
Phones nvarchar(max) '$.Phones' AS Json)
CROSS APPLY OPENJSON(Phones)
嗯,你总是可以这样做:
Id First Name Last Name Phone
2 John Smith 123
2 John Smith 345
2 John Smith 678
DECLARE @json NVARCHAR(MAX)
SET @json =
N'[
{ "id" : 2,"info": { "name": "John", "surname": "Smith" }, "Phones": ["123","345","678"] },
{ "id" : 3,"info": { "name": "Jane", "surname": "Smith" }, "Phones": ["321","543"] }
]';
WITH CTE AS (
SELECT id, firstName, lastName, phones
FROM OPENJSON(@json)
WITH (
id INT 'strict $.id',
firstName NVARCHAR(50) '$.info.name',
lastName NVARCHAR(50) '$.info.surname',
phones NVARCHAR(MAX) '$.Phones' AS JSON
)
)
SELECT c.id, c.firstName, c.lastName, p.value as phone
FROM CTE c
CROSS APPLY OPENJSON(c.phones) p
SELECT ID, FirstName, LastName, value
FROM OPENJSON(@json)
WITH(ID int '$.id',
FirstName nvarchar(50) '$.info.name',
LastName nvarchar(50) '$.info.surname',
Phones nvarchar(max) '$.Phones' AS Json)
CROSS APPLY OPENJSON(Phones)
希望这有帮助。您可以使用C#library
它是一个功能强大的工具,如果Json具有嵌套级别,它可以维护Json中的sql关系 伟大的解决方案,我被困在这个
电话NVARCHAR(MAX)作为JSON的问题上,所以实现了它像值一样clause@TheGameiswar:如果严格限制(和/或已知)值的数量,则从数组中显式提取它们可能比第二次OPENJSON
要快。但是我没有任何计时JSON解析的经验,所以现在还不需要优化。:-)是的,你是对的,刚刚看到了执行计划,原始Json的成本为0,外部应用下面的Json的成本为20