Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como importar um arquivo JSON para uma tabela do SQL Server


Se você tiver um documento JSON, há várias maneiras de colocá-lo no SQL Server.

Se for um documento pequeno, você pode copiar e colar seu conteúdo. Se for um documento maior (ou mesmo pequeno), convém importar o arquivo inteiro.

Este artigo apresenta um exemplo de importação de um arquivo JSON para um banco de dados SQL Server.

Selecionando o conteúdo do arquivo JSON


T-SQL inclui o OPENROWSET() função, que pode ler dados de qualquer arquivo na unidade local ou rede e retorná-lo como um conjunto de linhas. Para fazer isso, execute esta função com o BULK opção.

Embora este artigo tenha sido escrito especificamente para importar o arquivo JSON para uma tabela, você também pode usar OPENROWSET() para ler de um arquivo de dados sem necessariamente carregá-lo em uma tabela.

Isso permite que você verifique os dados primeiro, antes de carregá-los na tabela.

Aqui está um exemplo de como selecionar o conteúdo de um arquivo 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" }
        ]
    }
}              |
+--------------+

Nesse caso, o sistema de arquivos é Linux e, portanto, as convenções de caminho do Linux são usadas ao especificar qual arquivo carregar.

Se você estiver no Windows, o caminho do arquivo pode ser mais parecido com este:
SELECT BulkColumn FROM OPENROWSET (
    BULK 'D:\data\pets.json', 
    SINGLE_CLOB
    ) AS [Json];

De qualquer forma, podemos ver o conteúdo do arquivo JSON acima. Vamos agora carregá-lo em uma tabela.

Carregar em uma tabela


Podemos modificar a instrução anterior, para que o conteúdo do arquivo seja importado diretamente para uma tabela.
-- 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" }
        ]
    }
}              |
+--------------+

Fazer isso cria a tabela e insere o JSON.

Observe que ao usar OPENROWSET() com o BULK opção, você também deve fornecer um nome de correlação (também conhecido como variável de intervalo ou alias) no FROM cláusula.

Se você não fornecer um nome de correlação, receberá um erro.

No meu exemplo, usei Json como o nome da correlação, mas sinta-se à vontade para escolher o seu.

Analisar o JSON em linhas e colunas


É aqui que as coisas ficam excitantes. Não só podemos carregar o conteúdo de um arquivo e importá-lo para uma coluna da tabela, como também podemos separar seu conteúdo em várias linhas e colunas.

OPENJSON() é uma função com valor de tabela que converte documentos JSON em um formato tabular.

Portanto, podemos usar OPENJSON() para converter o conteúdo do nosso arquivo JSON em formato tabular e inseri-lo em uma tabela ou em várias tabelas, se esse for o objetivo.

Mas, novamente, podemos verificar nossos dados antes de inseri-los em qualquer tabela.
-- 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)

Isso é exatamente como ele ficará uma vez inserido em duas tabelas.

Para inseri-lo nas tabelas, tudo o que precisamos fazer é adicionar INTO TableName entre o SELECT parte e FROM (onde TableName é o nome da tabela que queremos criar).
-- 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)

Essas tabelas foram criadas usando as definições de coluna que fornecemos no WITH cláusula.

Cada chave JSON é mapeada para um nome de coluna de nossa escolha.

Você também pode basear os nomes das colunas nos nomes das chaves no arquivo JSON. Se você fizer isso, não precisará mapeá-los com um caminho, pois OPENJSON() irá combiná-los automaticamente com os nomes das chaves JSON.

Por exemplo, em vez de usar a seguinte cláusula WITH:
WITH  (
            DogId     int             '$.id',  
            DogName   varchar(60)     '$.name', 
            Sex       varchar(6)      '$.sex'  
        ) AS [Dogs]

Você poderia usar isso:
WITH  (
        id     int,  
        name   varchar(60), 
        sex    varchar(6)  
    ) AS [Dogs]

Carregar o JSON em uma variável


Outra maneira de fazer isso seria carregar o JSON carregado em uma variável e, em seguida, passar essa variável para o OPENJSON() função.
-- 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)

Novamente, para inserir isso em uma tabela, adicionaríamos INTO TableName após o SELECT parte (onde TableName é o nome da tabela que você deseja criar).

Carregar um subobjeto inteiro em uma coluna


Se você quiser que subobjetos inteiros residam em sua própria coluna, você pode usar o AS JSON opção do WITH cláusula.

Por exemplo, em vez de ter cada gato e cachorro distribuídos em três colunas, todo o fragmento JSON pode ocupar uma coluna. Cada animal ainda terá sua própria linha.

Aqui está um exemplo do que quero dizer.
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)