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

Come importare un file JSON in una tabella di SQL Server

Se si dispone di un documento JSON, esistono diversi modi per inserirlo in SQL Server.

Se si tratta di un piccolo documento, puoi copiarne e incollarne il contenuto. Se si tratta di un documento più grande (o anche piccolo), potresti voler importare l'intero file.

Questo articolo presenta un esempio di importazione di un file JSON in un database di SQL Server.

Selezione del contenuto del file JSON

T-SQL include OPENROWSET() funzione, che può leggere i dati da qualsiasi file sull'unità locale o sulla rete e restituirli come un set di righe. Per farlo, esegui questa funzione con il BULK opzione.

Sebbene questo articolo sia stato scritto specificamente per importare il file JSON in una tabella, puoi anche utilizzare OPENROWSET() leggere da un file di dati senza necessariamente caricarlo in una tabella.

Ciò ti consente di controllare i dati prima di caricarli nella tabella.

Ecco un esempio di selezione del contenuto di un file JSON.

SELECT BulkColumn FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB
    ) AS [Json];

Risultato:

+--------------+
| BulkColumn   |
|--------------|
| { 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "id" : 1, "name" : "Fetch", "sex" : "Male" },
            { "id" : 2, "name" : "Fluffy", "sex" : "Male" },
            { "id" : 3, "name" : "Wag", "sex" : "Female" }
        ]
    }
}              |
+--------------+

In questo caso, il file system è Linux, quindi le convenzioni del percorso Linux vengono utilizzate quando si specifica quale file caricare.

Se sei su Windows, il percorso del tuo file potrebbe essere più simile a questo:

SELECT BulkColumn FROM OPENROWSET (
    BULK 'D:\data\pets.json', 
    SINGLE_CLOB
    ) AS [Json];

Ad ogni modo, possiamo vedere il contenuto del file JSON sopra. Ora carichiamolo in una tabella.

Caricalo in una tabella

Possiamo modificare l'istruzione precedente, in modo che il contenuto del file venga importato direttamente in una tabella.

-- Import it directly into the table
SELECT BulkColumn INTO ImportedJson FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB
    ) AS [Json];

-- Select the contents of the table
SELECT * FROM ImportedJson;

Risultato:

+--------------+
| BulkColumn   |
|--------------|
| { 
    "pets" : {
            "cats" : [
            { "id" : 1, "name" : "Fluffy", "sex" : "Female" },
            { "id" : 2, "name" : "Long Tail", "sex" : "Female" },
            { "id" : 3, "name" : "Scratch", "sex" : "Male" }
        ],
            "dogs" : [
            { "id" : 1, "name" : "Fetch", "sex" : "Male" },
            { "id" : 2, "name" : "Fluffy", "sex" : "Male" },
            { "id" : 3, "name" : "Wag", "sex" : "Female" }
        ]
    }
}              |
+--------------+

In questo modo viene creata la tabella e viene inserito il JSON.

Nota che quando usi OPENROWSET() con il BULK opzione, devi anche fornire un nome di correlazione (noto anche come variabile di intervallo o alias) in FROM clausola.

Se non fornisci un nome di correlazione, riceverai un errore.

Nel mio esempio, ho usato Json come nome della correlazione, ma sentiti libero di scegliere il tuo.

Analizza il JSON in righe e colonne

È qui che le cose si fanno eccitanti. Non solo possiamo caricare il contenuto di un file e importarlo in una colonna di tabella, ma possiamo anche separarne il contenuto su più righe e colonne.

OPENJSON() è una funzione con valori di tabella che converte i documenti JSON in un formato tabulare.

Pertanto, possiamo utilizzare OPENJSON() per convertire il contenuto del nostro file JSON in formato tabulare e inserirlo in una tabella o in più tabelle se questo è l'obiettivo.

Ma ancora una volta, possiamo controllare i nostri dati prima di inserirli in qualsiasi tabella.

-- Select the cats
SELECT Cats.* FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB) AS [Json]
    CROSS APPLY OPENJSON ( BulkColumn, '$.pets.cats' )
    WITH  (
            CatId     int             '$.id',  
            CatName   varchar(60)     '$.name', 
            Sex       varchar(6)      '$.sex'  
        ) AS [Cats]

-- Select the dogs
SELECT Dogs.* FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB) AS [Json]    
    CROSS APPLY OPENJSON ( BulkColumn, '$.pets.dogs' )
    WITH  (
            DogId     int             '$.id',  
            DogName   varchar(60)     '$.name', 
            Sex       varchar(6)      '$.sex'  
        ) AS [Dogs]

Risultato:

+---------+-----------+--------+
| CatId   | CatName   | Sex    |
|---------+-----------+--------|
| 1       | Fluffy    | Female |
| 2       | Long Tail | Female |
| 3       | Scratch   | Male   |
+---------+-----------+--------+
(3 rows affected)
+---------+-----------+--------+
| DogId   | DogName   | Sex    |
|---------+-----------+--------|
| 1       | Fetch     | Male   |
| 2       | Fluffy    | Male   |
| 3       | Wag       | Female |
+---------+-----------+--------+
(3 rows affected)

Questo è esattamente come apparirà una volta inseriti in due tabelle.

Per inserirlo nelle tabelle, tutto ciò che dobbiamo fare è aggiungere INTO TableName tra il SELECT parte e FROM (dove TableName è il nome della tabella che vogliamo creare).

-- Insert cats into a table
SELECT Cats.* INTO ImportedCats
FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB) AS [Json]
    CROSS APPLY OPENJSON ( BulkColumn, '$.pets.cats' )
    WITH  (
            CatId     int             '$.id',  
            CatName   varchar(60)     '$.name', 
            Sex       varchar(6)      '$.sex'  
        ) AS [Cats]

-- Insert dogs into a table
SELECT Dogs.* INTO ImportedDogs
FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB) AS [Json]    
    CROSS APPLY OPENJSON ( BulkColumn, '$.pets.dogs' )
    WITH  (
            DogId     int             '$.id',  
            DogName   varchar(60)     '$.name', 
            Sex       varchar(6)      '$.sex'  
        ) AS [Dogs]

-- Select the results from both tables
SELECT * FROM ImportedCats
SELECT * FROM ImportedDogs

Risultato:

+---------+-----------+--------+
| CatId   | CatName   | Sex    |
|---------+-----------+--------|
| 1       | Fluffy    | Female |
| 2       | Long Tail | Female |
| 3       | Scratch   | Male   |
+---------+-----------+--------+
(3 rows affected)
+---------+-----------+--------+
| DogId   | DogName   | Sex    |
|---------+-----------+--------|
| 1       | Fetch     | Male   |
| 2       | Fluffy    | Male   |
| 3       | Wag       | Female |
+---------+-----------+--------+
(3 rows affected)

Queste tabelle sono state create utilizzando le definizioni di colonna che abbiamo fornito in WITH clausola.

Ogni chiave JSON è mappata su un nome di colonna di nostra scelta.

Puoi anche basare i nomi delle colonne sui nomi delle chiavi nel file JSON. Se lo fai, non è necessario mapparli con un percorso, come OPENJSON() li abbinerà automaticamente ai nomi delle chiavi JSON.

Ad esempio, invece di utilizzare la seguente clausola WITH:

WITH  (
            DogId     int             '$.id',  
            DogName   varchar(60)     '$.name', 
            Sex       varchar(6)      '$.sex'  
        ) AS [Dogs]

Potresti usare questo:

WITH  (
        id     int,  
        name   varchar(60), 
        sex    varchar(6)  
    ) AS [Dogs]

Carica il JSON in una variabile

Un altro modo per farlo sarebbe caricare il JSON caricato in una variabile, quindi passare quella variabile a OPENJSON() funzione.

-- Declare variable
DECLARE @json nvarchar(max);

-- Upload JSON data into that variable
SELECT @json = BulkColumn FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB
    ) AS [Json];

-- Select the cats from that variable
SELECT * FROM OPENJSON(@json, '$.pets.cats')
WITH  (
        CatId     int             '$.id',  
        CatName   varchar(60)     '$.name', 
        Sex       varchar(6)      '$.sex'   
    );

-- Select the dogs from that variable
SELECT * FROM OPENJSON(@json, '$.pets.dogs')
WITH  (
        DogId     int             '$.id',  
        DogName   varchar(60)     '$.name', 
        Sex       varchar(6)      '$.sex'  
    );

Risultato:

+---------+-----------+--------+
| CatId   | CatName   | Sex    |
|---------+-----------+--------|
| 1       | Fluffy    | Female |
| 2       | Long Tail | Female |
| 3       | Scratch   | Male   |
+---------+-----------+--------+
(3 rows affected)
+---------+-----------+--------+
| DogId   | DogName   | Sex    |
|---------+-----------+--------|
| 1       | Fetch     | Male   |
| 2       | Fluffy    | Male   |
| 3       | Wag       | Female |
+---------+-----------+--------+
(3 rows affected)

Ancora una volta, per inserirlo in una tabella, aggiungeremo INTO TableName dopo il SELECT parte (dove TableName è il nome della tabella che vuoi creare).

Carica un intero oggetto secondario in una colonna

Se desideri che interi oggetti secondari risiedano nella propria colonna, puoi utilizzare AS JSON opzione del WITH clausola.

Ad esempio, invece di avere ogni cane e gatto distribuito su tre colonne, il loro intero frammento JSON potrebbe occupare una colonna. Ogni animale avrà ancora la propria fila.

Ecco un esempio di cosa intendo.

SELECT Cats.* FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB) AS [Json]
    CROSS APPLY OPENJSON ( BulkColumn, '$.pets.cats' )
    WITH  (
            Cats nvarchar(max) '$' AS JSON   
        ) AS [Cats]

SELECT Dogs.* FROM OPENROWSET (
    BULK '/var/opt/mssql/bak/pets.json', 
    SINGLE_CLOB) AS [Json]    
    CROSS APPLY OPENJSON ( BulkColumn, '$.pets.dogs' )
    WITH  (
            Dogs nvarchar(max) '$' AS JSON   
        ) AS [Dogs]

Risultato:

+------------------------------------------------------+
| Cats                                                 |
|------------------------------------------------------|
| { "id" : 1, "name" : "Fluffy", "sex" : "Female" }    |
| { "id" : 2, "name" : "Long Tail", "sex" : "Female" } |
| { "id" : 3, "name" : "Scratch", "sex" : "Male" }     |
+------------------------------------------------------+
(3 rows affected)
+-------------------------------------------------+
| Dogs                                            |
|-------------------------------------------------|
| { "id" : 1, "name" : "Fetch", "sex" : "Male" }  |
| { "id" : 2, "name" : "Fluffy", "sex" : "Male" } |
| { "id" : 3, "name" : "Wag", "sex" : "Female" }  |
+-------------------------------------------------+
(3 rows affected)