2016-07-20 30 views
2

JSON形式のデータがあります。以下の例を確認できます:SQL Serverで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" 
     } 
    ] 
} 
] 

を、私は、Microsoftが保存し、SQL Server 2016年にJSON形式を照会するためのサポートが導入されていることを知っているが、それは取得することはできません:私はそのようになり、結果を取得する必要があります階層的な結果。これはリレーショナルデータベースなので、結果はテーブルとして「フラット」になります。 JSONは動的な構造を持つことができるので、データベース内のテーブルへのJSONのマッピングもできません。車に乗っている人のリスト、または書籍を持った書店などです。

私はMongoDBのようなNOSQLデータベースを使用することができますが、私のプロジェクトでは追加のデータベースを避けたいと思います。

このような問題のためのベストプラクティスと.NETでの実行方法を知りたいと思います。

答えて

1

を取得します。

を作成したと、このデータのサンプルでテスト:

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 

CarsUsers

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 

この結果は、上記の表に挿入することができます。

+0

ありがとうございます。私がdbに格納するJSONは動的構造を持つことができるため、最初の部分(dbをテーブルを作成する部分)は私の場合は不可能です。私はどのテーブルが私のために建てられるのか予測できません。要約すると、JSONは1つの列に1つのレコードとしてDBに格納する必要があります。 2番目の部分は私にとって本当に重要です。結果をJSON形式で返すことができるかどうかはわかりませんでした。それは私の多くの助けになる:)同じ結果を返すようにSELECTクエリを変更しようとすることができますが、あなたは1つだけのテーブルがある場合など。 JsonDataTableにはJSONの例がすべて含まれています。 – Ellbar

+0

JSONをいくつかの列に保存し、予測できない構造を持つかもしれないが、フィルタリングされたデータを取得する必要がある場合 - パーサーの種類が必要で、SQLでC#またはPHPやその他の言語実際、いくつかのテーブルをJSONに変換することはできますが、このシナリオでは役に立ちません。 – gofr1

+0

私は1つのアイデアを得た、私は明日それをテストすることができ、私の答えにこれを追加します。 – gofr1

関連する問題