sql-server - 如何在 SQL Server 中存储、过滤和检索 JSON 数据

标签 sql-server json asp.net-mvc mongodb

我有 JSON 格式的数据。您可以查看以下示例:

[
{
"firstName": John,
"lastName": Smith,
"cars": [
      {
        "id": 0,
        "name": "BMW"
      },
      {
        "id": 1,
        "name": "Mercedes"
      },
      {
        "id": 2,
        "name": "Audi"
      }
    ]
}
{
"firstName": Adam
"lastName": Sheen,
"cars": [
      {
        "id": 0,
        "name": "Ferrari"
      },
      {
        "id": 1,
        "name": "Mercedes"
      }
    ]
}
]

我必须以某种方式存储这些数据并能够对其进行过滤。结果也应该是 JSON 格式,因为它将在整个过程的下一步中使用。我的 ASP.NET 应用程序使用 SQL SERVER(2012 和 2016)。

假设用户想要获得所有拥有名为“Ferrari”的汽车的人。我应该得到这样的结果:

[
{
"firstName": Adam
"lastName": Sheen,
"cars": [
      {
        "id": 0,
        "name": "Ferrari"
      },
      {
        "id": 1,
        "name": "Mercedes"
      }
    ]
}
]

我已经花了一些时间进行研究,我知道微软在 SQL SERVER 2016 中引入了对存储和查询 JSON 格式的支持,但它不允许获取分层结果。这是关系数据库,因此结果将像表一样“平坦”。将 JSON 映射到数据库中的表也是不可能的,因为 JSON 可以具有动态结构。它可以是有车的人的列表,也可以是有书的书店。

我知道我可以使用像 MongoDB 这样的 NOSQL 数据库,但我想避免在我的项目中使用额外的数据库。

我想知道此类问题的最佳实践以及如何在 .NET 中完成。

最佳答案

检索:

刚刚创建并测试了这个数据样本:

CREATE TABLE Users (
    userid int identity(1,1) not null,
    firstName nvarchar(50),
    lastName nvarchar(50)
)

CREATE TABLE Cars (
    id int identity(1,1) not null,
    name nvarchar(50)
)

CREATE TABLE CarsUsers (
    userid int not null,
    id int not null

)

ALTER TABLE Users WITH CHECK   
ADD CONSTRAINT PK_userid PRIMARY KEY CLUSTERED (userid)  

ALTER TABLE Cars WITH CHECK   
ADD CONSTRAINT PK_carid PRIMARY KEY CLUSTERED (id) 

ALTER TABLE CarsUsers WITH CHECK   
ADD CONSTRAINT PK_userid_id PRIMARY KEY CLUSTERED (userid, id)  

ALTER TABLE CarsUsers 
ADD CONSTRAINT FK_userid FOREIGN KEY (userid)  
    REFERENCES Users (userid)  

ALTER TABLE CarsUsers 
ADD CONSTRAINT FK_carid FOREIGN KEY (id)  
    REFERENCES Cars (id)  

INSERT INTO Users VALUES ('John', 'Smith'),('Adam','Sheen')

INSERT INTO Cars VALUES ('BMW'),('Mercedes'),('Audi')

INSERT INTO CarsUsers
SELECT  userid,
        id
FROM Cars
CROSS JOIN Users

所以我在表格中获取了这些数据。

用户

userid  firstName   lastName
1       John        Smith
2       Adam        Sheen

汽车

id  name
1   BMW
2   Mercedes
3   Audi

汽车用户

userid  id
1       1
1       2
1       3
2       1
2       2
2       3

然后在 SQL 2016 中运行此查询:

SELECT  u.firstName,
        u.LastName,
        (SELECT c.id,
                c.name
        FROM Cars c
        INNER JOIN CarsUsers cu
            ON u.userid = cu.userid
        WHERE c.id = cu.id
        FOR JSON PATH) as cars
FROM Users u
WHERE u.userid = 1
FOR JSON PATH

我会得到:

[
{
"firstName":"John",
"LastName":"Smith",
"cars":[
    {
        "id":1,
        "name":"BMW"
    },
    {
        "id":2,
        "name":"Mercedes"
    },
    {
        "id":3,
        "name":"Audi"
    }
    ]
}
]

因此 - 您可以从平面表中获取分层 JSON。

商店

正在尝试加载(在您的样本中添加小修复)。

DECLARE @json NVARCHAR(MAX) = N'[
{
"firstName":"John",
"lastName":"Smith",
"cars": [
      {
        "id":0,
        "name":"BMW"
      },
      {
        "id":1,
        "name":"Mercedes"
      },
      {
        "id":2,
        "name":"Audi"
      }
    ]
},
{
"firstName":"Adam",
"lastName":"Sheen",
"cars": [
      {
        "id":0,
        "name":"Ferrari"
      },
      {
        "id":1,
        "name":"Mercedes"
      }
    ]
}
]'  

SELECT  firstName,
        lastName,
        id,
        name
FROM OPENJSON(@json) 
WITH (   
    firstName nvarchar(200) '$.firstName',  
    lastName nvarchar(200) '$.lastName',  
    cars  nvarchar(MAX)  AS JSON
)
CROSS APPLY OPENJSON (cars) 
            WITH (
                id int '$.id',
                name nvarchar(200) '$.name'
                )

输出:

firstName   lastName    id  name
John        Smith       0   BMW
John        Smith       1   Mercedes
John        Smith       2   Audi
Adam        Sheen       0   Ferrari
Adam        Sheen       1   Mercedes

此结果可能会插入到上面列出的表格中。

关于sql-server - 如何在 SQL Server 中存储、过滤和检索 JSON 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38480263/

相关文章:

mysql - MsSQL 到 MySQL 的迁移

mysql - 我如何决定何时使用右连接/左连接或内连接或者如何确定哪个表在哪一侧?

java - 如何在 Hibernate native 查询中使用常量?

java - 如何将http:namenode-ip:50070/conf XML响应转换为JSON类型?

sql - 在 JSON 上查询 Hive 的 EOF 异常

javascript - 为什么我的脚本包会随着 ASP.Net MVC 中的每个页面 View 加载?

sql - EF Core Group By 正在使用 sqlite 而不是 SQL Server

c# - LINQ,查询的大过滤器

asp.net-mvc - <style> 中的 Razor 语法

java - 使用 JSOUP 编写 JSON