Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come inserire JSON in una tabella in SQL Server

Se hai un documento JSON che devi inserire in una tabella in un database di SQL Server, il OPENJSON() la funzione potrebbe essere proprio ciò di cui hai bisogno.

OPENJSON() è una funzione con valori di tabella che restituisce JSON in formato tabulare. Cioè, converte il tuo JSON in un set di risultati tabulare composto da righe e colonne. Pertanto, ti consente di inserirlo in una tabella.

Esempio 1 – SELEZIONA IN

In questo esempio, utilizziamo SELECT * INTO per creare una nuova tabella e inserirvi il contenuto del documento 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   
    );

Per prima cosa ho dichiarato una variabile e ci ho inserito il JSON. Quindi ho usato un SELECT * INTO dichiarazione per inserirne il contenuto.

Tuttavia, noterai che ho usato una clausola WITH per definire uno schema. Fondamentalmente quello che sto facendo qui è creare i miei nomi di colonna e i rispettivi tipi di dati, quindi mappare ciascuna chiave JSON con una colonna.

Nell'ultima riga, utilizzo AS JSON per specificare che il contenuto di quella colonna è un oggetto o una matrice JSON.

Questo diventerà chiaro quando seleziono il contenuto della tabella.

Facciamolo.

SELECT * FROM JsonCats1;

Risultato:

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

Quindi possiamo vedere che le prime tre colonne contengono ciascuna un valore diverso dal documento JSON e l'ultima colonna contiene il JSON effettivo per ogni elemento dell'array.

Possiamo anche usare sys.column la visualizzazione del catalogo di sistema controlla i nomi e i tipi delle colonne della tabella.

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

Risultato:

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

Ancora una volta, esattamente come l'avevamo specificato.

Nota che sys.columns restituisce sempre un max_length di -1 quando il tipo di dati della colonna è varchar(max) , nvarchar(max) , variabile(max) o xml . Abbiamo specificato nvarchar(max) e quindi il valore di -1 è esattamente come previsto.

Tieni inoltre presente che, quando utilizzi AS JSON (come abbiamo fatto nella quarta colonna), devi rendere quella colonna un nvarchar(max) .

Esempio 2 – INSERIRE IN

Ecco lo stesso esempio, tranne che questa volta inseriamo il JSON in una tabella già esistente.

Pertanto, la prima cosa che dobbiamo fare è creare la tabella:

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

Ora che l'abbiamo creato, possiamo procedere e inserire il contenuto del nostro documento JSON in quella tabella.

In questo modo:

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

L'unica differenza tra questo e l'esempio precedente è che ho sostituito il seguente bit:

SELECT * INTO JsonCats1

Con questo:

INSERT INTO JsonCats2
SELECT * 

Quindi, selezionando il contenuto della tabella si otterrà lo stesso risultato dell'esempio precedente.

SELECT * FROM JsonCats2;

Risultato:

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

Esempio 3:utilizzo dello schema predefinito

Negli esempi precedenti ho definito il mio schema. Cioè, ho specificato i nomi delle colonne per le tabelle e ho specificato i tipi di dati effettivi di quelle colonne.

Se non l'avessi fatto, OPENJSON() avrebbe utilizzato lo schema predefinito. Lo schema predefinito è costituito da tre colonne; chiave , valore e digita .

Ecco un esempio di utilizzo dello schema predefinito quando si inserisce JSON in una tabella.

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

Quindi l'unica differenza tra questo e il primo esempio è che ho rimosso l'intero WITH clausola. Questo è il bit che ha definito lo schema nei due esempi precedenti.

Ora controlliamo il contenuto della tabella.

SELECT * FROM JsonCats3;

Risultato:

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

Questa tabella contiene le tre colonne menzionate. La colonna del valore contiene ogni elemento dell'array.

Esempio 4:utilizzo di chiavi JSON come intestazioni di colonna

Questo esempio è un po' un incrocio tra i due esempi precedenti.

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

Stiamo ancora definendo il nostro schema, perché stiamo usando il WITH clausola. Ma noterai che non sto mappando i nomi delle colonne su nessun percorso JSON. Questo perché sto usando i nomi effettivi delle chiavi JSON.

Quando lo fai, OPENJSON() è abbastanza intelligente da abbinare i nomi delle colonne alle chiavi JSON.

Vediamo cosa c'è nella tabella.

SELECT * FROM JsonCats4;

Risultato:

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

Quindi i dati sono stati inseriti nella tabella, proprio come nei primi due esempi, ma questa volta i nomi delle colonne sono stati presi dal documento JSON.

Esempio 5:specificare meno colonne

Non è necessario includere tutti i valori del documento JSON se non sono necessari tutti. Puoi specificare solo quelli di cui hai bisogno.

Puoi farlo specificando le colonne in SELECT elenco.

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;

Risultato:

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

Un altro modo per farlo è rimuovere la colonna o le colonne pertinenti da WITH clausola.

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;

Risultato:

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

Anche se probabilmente è meglio fare entrambe le cose.

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;

Risultato:

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

Esempio 6:specificare meno righe

Puoi anche utilizzare la normale sintassi T-SQL per filtrare le righe, in modo che solo alcuni record vengano inseriti nella tabella.

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;

Risultato:

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

In questo caso ho usato un WHERE clausola per inserire solo le righe che mi interessano.

Importa JSON da un file

Puoi usare OPENJSON() insieme a OPENROWSET() funzione per importare un file JSON in una tabella.

Ciò ti consente di caricare i dati da un file JSON su un'unità locale o un'unità di rete. Ciò ti evita di dover copiare e incollare il contenuto del documento nel tuo codice SQL. Ciò può essere particolarmente utile quando si lavora con documenti JSON di grandi dimensioni.