sql >> Database >  >> RDS >> Sqlserver

JSON invoegen in een tabel in SQL Server

Als u een JSON-document hebt dat u in een tabel in een SQL Server-database moet invoegen, is de OPENJSON() functie kan precies zijn wat u nodig heeft.

OPENJSON() is een functie met tabelwaarde die JSON retourneert in tabelvorm. Dat wil zeggen, het converteert uw JSON naar een resultatenset in tabelvorm die bestaat uit rijen en kolommen. Daarom kunt u het in een tabel invoegen.

Voorbeeld 1 – SELECTEER IN

In dit voorbeeld gebruiken we SELECT * INTO om een ​​nieuwe tabel te maken en de inhoud van het JSON-document erin in te voegen.

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

Ik heb eerst een variabele gedeclareerd en de JSON erin geplaatst. Toen gebruikte ik een SELECT * INTO statement om de inhoud in te voegen.

U zult echter merken dat ik een WITH-component heb gebruikt om een ​​schema te definiëren. Wat ik hier eigenlijk doe, is mijn eigen kolomnamen en hun respectieve gegevenstypen maken en vervolgens elke JSON-sleutel toewijzen aan een kolom.

Op de laatste regel gebruik ik AS JSON om aan te geven dat de inhoud van die kolom een ​​JSON-object of -array is.

Dit wordt duidelijk als ik de inhoud van de tabel selecteer.

Laten we dat doen.

SELECT * FROM JsonCats1;

Resultaat:

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

We kunnen dus zien dat de eerste drie kolommen elk een andere waarde uit het JSON-document bevatten en de laatste kolom de daadwerkelijke JSON voor elk array-element.

We kunnen ook de sys.column . gebruiken systeemcatalogusweergave controleer de kolomnamen en typen van de tabel.

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

Resultaat:

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

Nogmaals, precies hoe we het hadden gespecificeerd.

Merk op dat sys.columns retourneert altijd een max_length van -1 wanneer het kolomgegevenstype varchar(max) . is , nvarchar(max) , varbinary(max) , of xml . We hebben nvarchar(max) . gespecificeerd en dus de waarde van -1 is precies zoals verwacht.

Houd er ook rekening mee dat, wanneer u AS JSON . gebruikt (zoals we deden in de vierde kolom), moet u van die kolom een ​​nvarchar(max) . maken .

Voorbeeld 2 – INVOEREN IN

Hier is hetzelfde voorbeeld, behalve dat we deze keer de JSON invoegen in een tabel die al bestaat.

Daarom moeten we eerst de tabel maken:

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

Nu we dat hebben gemaakt, kunnen we doorgaan en de inhoud van ons JSON-document in die tabel invoegen.

Zoals dit:

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

Het enige verschil tussen dit en het vorige voorbeeld is dat ik het volgende bit heb vervangen:

SELECT * INTO JsonCats1

Hiermee:

INSERT INTO JsonCats2
SELECT * 

Als u dus de inhoud van de tabel selecteert, krijgt u hetzelfde resultaat als in het vorige voorbeeld.

SELECT * FROM JsonCats2;

Resultaat:

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

Voorbeeld 3 – Het standaardschema gebruiken

In de voorgaande voorbeelden heb ik mijn eigen schema gedefinieerd. Dat wil zeggen, ik heb de namen van de kolommen voor de tabellen opgegeven en ik heb de feitelijke gegevenstypen van die kolommen opgegeven.

Als ik dat niet had gedaan, OPENJSON() het standaardschema zou hebben gebruikt. Het standaardschema bestaat uit drie kolommen; sleutel , waarde , en typ .

Hier is een voorbeeld van het gebruik van het standaardschema bij het invoegen van JSON in een tabel.

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

Dus het enige verschil tussen dit en het eerste voorbeeld is dat ik de hele WITH . heb verwijderd clausule. Dat is het bit dat het schema in de vorige twee voorbeelden definieerde.

Laten we nu de inhoud van de tabel controleren.

SELECT * FROM JsonCats3;

Resultaat:

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

Deze tabel bevat de drie kolommen zoals vermeld. De waardekolom bevat elk matrixelement.

Voorbeeld 4 – Gebruik JSON-sleutels als kolomkoppen

Dit voorbeeld is een beetje een kruising tussen de vorige twee voorbeelden.

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

We zijn nog steeds ons eigen schema aan het definiëren, omdat we de WITH . gebruiken clausule. Maar u zult merken dat ik de kolomnamen niet toewijs aan een JSON-pad. Dit komt omdat ik de werkelijke namen van de JSON-sleutels gebruik.

Wanneer u dat doet, OPENJSON() is slim genoeg om uw kolomnamen te matchen met de JSON-sleutels.

Laten we eens kijken wat er in de tabel staat.

SELECT * FROM JsonCats4;

Resultaat:

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

Dus de gegevens zijn in de tabel ingevoegd, net als in de eerste twee voorbeelden, maar deze keer zijn de kolomnamen overgenomen uit het JSON-document.

Voorbeeld 5 – Specificeer minder kolommen

U hoeft niet alle waarden uit het JSON-document op te nemen als u ze niet allemaal nodig heeft. U kunt alleen die specificeren die u nodig heeft.

U kunt dit doen door de kolommen op te geven in de SELECT lijst.

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;

Resultaat:

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

Een andere manier om dit te doen is door de relevante kolom(men) te verwijderen uit de WITH clausule.

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;

Resultaat:

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

Hoewel het waarschijnlijk beter is om beide te doen.

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;

Resultaat:

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

Voorbeeld 6 – Specificeer minder rijen

U kunt ook de normale T-SQL-syntaxis gebruiken om de rijen te filteren, zodat slechts enkele records in de tabel worden ingevoegd.

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;

Resultaat:

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

In dit geval gebruikte ik een WHERE clausule om alleen de rijen in te voegen waarin ik geïnteresseerd ben.

JSON importeren uit een bestand

U kunt OPENJSON() . gebruiken in combinatie met de OPENROWSET() functie om een ​​JSON-bestand in een tabel te importeren.

Hiermee kunt u de gegevens van een JSON-bestand op een lokale schijf of netwerkschijf uploaden. Hierdoor hoeft u de inhoud van het document niet te kopiëren en in uw SQL-code te plakken. Dit kan met name handig zijn bij het werken met grote JSON-documenten.


  1. Hoe zorg ik ervoor dat een gematerialiseerde view altijd up-to-date is?

  2. 3 manieren om de dagnaam van een datum te krijgen in SQL Server (T-SQL)

  3. Moet een MAMP ::1 retourneren als IP op localhost?

  4. Hoe verklein ik mijn SQL Server-database?