sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo importar un archivo JSON a una tabla de SQL Server

Si tiene un documento JSON, hay varias formas de introducirlo en SQL Server.

Si es un documento pequeño, puede copiar y pegar su contenido. Si se trata de un documento más grande (o incluso uno pequeño), es posible que desee importar el archivo completo.

Este artículo presenta un ejemplo de cómo importar un archivo JSON a una base de datos de SQL Server.

Seleccionar el contenido del archivo JSON

T-SQL incluye el OPENROWSET() función, que puede leer datos de cualquier archivo en el disco local o en la red, y devolverlos como un conjunto de filas. Para hacer eso, ejecute esta función con BULK opción.

Si bien este artículo se escribió específicamente para importar el archivo JSON a una tabla, también puede usar OPENROWSET() para leer de un archivo de datos sin necesariamente cargarlo en una tabla.

Esto le permite verificar los datos primero, antes de cargarlos en la tabla.

Este es un ejemplo de cómo seleccionar el contenido de un archivo JSON.

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

Resultado:

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

En este caso, el sistema de archivos es Linux, por lo que se utilizan las convenciones de ruta de Linux al especificar qué archivo cargar.

Si está en Windows, la ruta de su archivo podría parecerse más a esta:

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

De todos modos, podemos ver el contenido del archivo JSON arriba. Ahora carguémoslo en una tabla.

Cárgalo en una tabla

Podemos modificar la afirmación anterior, para que el contenido del archivo se importe directamente a una tabla.

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

Resultado:

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

Hacer eso crea la tabla e inserta el JSON.

Tenga en cuenta que al usar OPENROWSET() con el BULK opción, también debe proporcionar un nombre de correlación (también conocido como variable de rango o alias) en el FROM cláusula.

Si no proporciona un nombre de correlación, obtendrá un error.

En mi ejemplo, usé Json como el nombre de la correlación, pero siéntete libre de elegir el tuyo propio.

Analice el JSON en filas y columnas

Aquí es donde las cosas se ponen emocionantes. No solo podemos cargar el contenido de un archivo e importarlo en una columna de la tabla, sino que también podemos separar su contenido en varias filas y columnas.

OPENJSON() es una función con valores de tabla que convierte documentos JSON en un formato tabular.

Por lo tanto, podemos usar OPENJSON() para convertir el contenido de nuestro archivo JSON en formato tabular e insertarlo en una tabla o en varias tablas si ese es el objetivo.

Pero nuevamente, podemos verificar nuestros datos antes de insertarlos en cualquier tabla.

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

Resultado:

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

Así es exactamente como se verá una vez insertado en dos tablas.

Para insertarlo en las tablas, todo lo que necesitamos hacer es agregar INTO TableName entre SELECT parte y FROM (donde TableName es el nombre de la tabla que queremos crear).

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

Resultado:

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

Estas tablas se crearon usando las definiciones de columna que proporcionamos en WITH cláusula.

Cada clave JSON se asigna a un nombre de columna de nuestra elección.

También puede basar los nombres de las columnas en los nombres de las claves del archivo JSON. Si hace eso, no necesita mapearlos con una ruta, como OPENJSON() los emparejará automáticamente con los nombres de las claves JSON.

Por ejemplo, en lugar de usar la siguiente cláusula WITH:

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

Podrías usar esto:

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

Cargar el JSON en una variable

Otra forma de hacerlo sería cargar el JSON cargado en una variable y luego pasar esa variable a OPENJSON() función.

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

Resultado:

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

Nuevamente, para insertar esto en una tabla, agregaríamos INTO TableName después de SELECT parte (donde TableName es el nombre de la tabla que desea crear).

Cargar un subobjeto completo en una columna

Si desea que los subobjetos completos residan en su propia columna, puede usar el AS JSON opción del WITH cláusula.

Por ejemplo, en lugar de tener cada gato y perro distribuidos en tres columnas, su fragmento JSON completo podría ocupar una columna. Cada animal seguirá teniendo su propia fila.

Este es un ejemplo de lo que quiero decir.

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]

Resultado:

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