sql >> Databáze >  >> RDS >> Sqlserver

Jak vložit JSON do tabulky na SQL Server

Pokud máte dokument JSON, který potřebujete vložit do tabulky v databázi SQL Server, OPENJSON() funkce může být přesně to, co potřebujete.

OPENJSON() je funkce s tabulkovou hodnotou, která vrací JSON v tabulkovém formátu. To znamená, že převede váš JSON na tabulkovou sadu výsledků skládající se z řádků a sloupců. Umožňuje vám jej tedy vložit do tabulky.

Příklad 1 – VYBERTE DO

V tomto příkladu použijeme SELECT * INTO vytvořit novou tabulku a vložit do ní obsah dokumentu 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   
    );

Nejprve jsem deklaroval proměnnou a vložil do ní JSON. Pak jsem použil SELECT * INTO příkaz k vložení jeho obsahu.

Všimnete si však, že jsem k definování schématu použil klauzuli WITH. V podstatě to, co zde dělám, je vytváření vlastních názvů sloupců a jejich příslušných datových typů a poté mapování každého klíče JSON se sloupcem.

Na posledním řádku používám AS JSON k určení, že obsah tohoto sloupce je objekt nebo pole JSON.

To bude jasné, když vyberu obsah tabulky.

Pojďme na to.

SELECT * FROM JsonCats1;

Výsledek:

+---------+-----------+--------+------------------------------------------------------+
| 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" }     |
+---------+-----------+--------+------------------------------------------------------+

Můžeme tedy vidět, že každý z prvních tří sloupců obsahuje jinou hodnotu než v dokumentu JSON a poslední sloupec obsahuje skutečný JSON pro každý prvek pole.

Můžeme také použít sys.column zobrazení systémového katalogu zkontrolujte názvy a typy sloupců tabulky.

SELECT
    name AS [Column],
    TYPE_NAME(system_type_id) AS [Type],
    max_length
FROM sys.columns 
WHERE OBJECT_ID('JsonCats2') = object_id;

Výsledek:

+----------+----------+--------------+
| Column   | Type     | max_length   |
|----------+----------+--------------|
| Cat Id   | int      | 4            |
| Cat Name | varchar  | 60           |
| Sex      | varchar  | 6            |
| Cats     | nvarchar | -1           |
+----------+----------+--------------+

Opět přesně tak, jak jsme to specifikovali.

Všimněte si, že sys.columns vždy vrátí max_length z -1 když je datový typ sloupce varchar(max) , nvarchar(max) , varbinary(max) nebo xml . Zadali jsme nvarchar(max) a tedy hodnotu -1 je přesně podle očekávání.

Všimněte si také, že když používáte AS JSON (stejně jako ve čtvrtém sloupci), musíte tento sloupec nastavit jako nvarchar(max) .

Příklad 2 – INSERT INTO

Zde je stejný příklad, ale tentokrát vložíme JSON do tabulky, která již existuje.

Proto první věc, kterou musíme udělat, je vytvořit tabulku:

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

Nyní, když jsme to vytvořili, můžeme pokračovat a vložit obsah našeho dokumentu JSON do této tabulky.

Takhle:

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   
    );

Jediný rozdíl mezi tímto a předchozím příkladem je ten, že jsem nahradil následující bit:

SELECT * INTO JsonCats1

S tímto:

INSERT INTO JsonCats2
SELECT * 

Takže výběr obsahu tabulky poskytne stejný výsledek jako v předchozím příkladu.

SELECT * FROM JsonCats2;

Výsledek:

+---------+-----------+--------+------------------------------------------------------+
| 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" }     |
+---------+-----------+--------+------------------------------------------------------+

Příklad 3 – Použití výchozího schématu

V předchozích příkladech jsem definoval vlastní schéma. To znamená, že jsem určil názvy sloupců pro tabulky a uvedl skutečné datové typy těchto sloupců.

Pokud bych to neudělal, OPENJSON() by použil výchozí schéma. Výchozí schéma se skládá ze tří sloupců; klíč , hodnota a zadejte .

Zde je příklad použití výchozího schématu při vkládání JSON do tabulky.

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');

Takže jediný rozdíl mezi tímto a prvním příkladem je ten, že jsem odstranil celý WITH doložka. To je bit, který definoval schéma v předchozích dvou příkladech.

Nyní se podívejme na obsah tabulky.

SELECT * FROM JsonCats3;

Výsledek:

+-------+------------------------------------------------------+--------+
| 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      |
+-------+------------------------------------------------------+--------+

Tato tabulka obsahuje tři uvedené sloupce. Sloupec value obsahuje každý prvek pole.

Příklad 4 – Použití klíčů JSON jako záhlaví sloupců

Tento příklad je tak trochu kříženec mezi předchozími dvěma příklady.

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)
);

Stále definujeme naše vlastní schéma, protože používáme WITH doložka. Ale všimnete si, že nemapuji názvy sloupců na žádnou cestu JSON. Je to proto, že používám skutečné názvy klíčů JSON.

Když to uděláte, OPENJSON() je dostatečně chytrý na to, aby odpovídal názvům sloupců klíčům JSON.

Podívejme se, co je v tabulce.

SELECT * FROM JsonCats4;

Výsledek:

+------+-----------+--------+
| id   | name      | sex    |
|------+-----------+--------|
| 1    | Fluffy    | Female |
| 2    | Long Tail | Female |
| 3    | Scratch   | Male   |
+------+-----------+--------+

Takže data byla vložena do tabulky, stejně jako v prvních dvou příkladech, ale tentokrát byly názvy sloupců převzaty z dokumentu JSON.

Příklad 5 – Zadání méně sloupců

Pokud je nepotřebujete všechny, nemusíte zahrnout všechny hodnoty z dokumentu JSON. Můžete zadat pouze ty, které potřebujete.

Můžete to provést zadáním sloupců v SELECT seznam.

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;

Výsledek:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
| 3    | Scratch   |
+------+-----------+

Dalším způsobem, jak to udělat, je odstranit příslušné sloupce z WITH doložka.

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;

Výsledek:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
| 3    | Scratch   |
+------+-----------+

I když je pravděpodobně lepší udělat obojí.

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;

Výsledek:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
| 3    | Scratch   |
+------+-----------+

Příklad 6 – Zadání méně řádků

Pro filtrování řádků můžete také použít normální syntaxi T-SQL, takže do tabulky budou vloženy pouze některé záznamy.

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;

Výsledek:

+------+-----------+
| id   | name      |
|------+-----------|
| 1    | Fluffy    |
| 2    | Long Tail |
+------+-----------+

V tomto případě jsem použil WHERE klauzule pro vložení pouze řádků, které mě zajímají.

Importujte JSON ze souboru

Můžete použít OPENJSON() ve spojení s OPENROWSET() funkce pro import souboru JSON do tabulky.

To vám umožní nahrát data ze souboru JSON na místní jednotku nebo síťovou jednotku. To vám ušetří nutnost kopírovat a vkládat obsah dokumentu do kódu SQL. To může být výhodné zejména při práci s velkými dokumenty JSON.


  1. Jak nainstalovat WordPress:Serverový software

  2. Poslední slovo ve větě:V SQL (možné regulární výrazy?)

  3. SQLServer IDENTITY Sloupec s textem

  4. SQL MAX více sloupců?