SQL Serverデータベースのテーブルに挿入する必要のあるJSONドキュメントがある場合は、OPENJSON()
機能はまさにあなたが必要とするものかもしれません。
OPENJSON()
表形式でJSONを返すテーブル値関数です。つまり、JSONを行と列で構成される表形式の結果セットに変換します。したがって、テーブルに挿入することができます。
例1– SELECT INTO
この例では、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" } | +---------+-----------+--------+------------------------------------------------------+
したがって、最初の3つの列にはそれぞれ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) 、 varbinary(max) 、または xml 。 nvarchar(max)を指定しました したがって、-1
の値 期待どおりです。
AS JSON
を使用する場合も注意してください (4番目の列で行ったように)その列を 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()
デフォルトのスキーマを使用します。デフォルトのスキーマは3つの列で構成されています。 キー 、値 、およびタイプ 。
これは、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
全体を削除したことです。 句。これが、前の2つの例でスキーマを定義したビットです。
それでは、テーブルの内容を確認しましょう。
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 | +-------+------------------------------------------------------+--------+
このテーブルには、前述の3つの列が含まれています。値の列には、各配列要素が含まれています。
例4–列ヘッダーとしてJSONキーを使用する
この例は、前の2つの例を少し組み合わせたものです。
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 | +------+-----------+--------+
したがって、最初の2つの例と同様に、データがテーブルに挿入されていますが、今回は列名が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ドキュメントを操作する場合に特に役立ちます。