Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách chèn JSON vào bảng trong SQL Server

Nếu bạn có tài liệu JSON mà bạn cần chèn vào bảng trong cơ sở dữ liệu SQL Server, thì OPENJSON() chức năng có thể là những gì bạn cần.

OPENJSON() là một hàm có giá trị bảng trả về JSON ở định dạng bảng. Nghĩa là, nó chuyển đổi JSON của bạn thành một tập hợp kết quả dạng bảng bao gồm các hàng và cột. Do đó, nó cho phép bạn chèn nó vào một bảng.

Ví dụ 1 - CHỌN VÀO

Trong ví dụ này, chúng tôi sử dụng SELECT * INTO để tạo một bảng mới và chèn nội dung của tài liệu JSON vào đó.

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

Đầu tiên tôi đã khai báo một biến và đặt JSON vào đó. Sau đó, tôi sử dụng SELECT * INTO câu lệnh để chèn nội dung của nó.

Tuy nhiên, bạn sẽ nhận thấy rằng tôi đã sử dụng mệnh đề WITH để xác định một lược đồ. Về cơ bản những gì tôi đang làm ở đây là tạo tên cột của riêng tôi và các kiểu dữ liệu tương ứng của chúng, sau đó ánh xạ từng khóa JSON với một cột.

Ở dòng cuối cùng, tôi sử dụng AS JSON để chỉ định rằng nội dung của cột đó là một đối tượng hoặc mảng JSON.

Điều này sẽ trở nên rõ ràng khi tôi chọn nội dung của bảng.

Hãy làm điều đó.

SELECT * FROM JsonCats1;

Kết quả:

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

Vì vậy, chúng ta có thể thấy rằng ba cột đầu tiên chứa một giá trị khác với tài liệu JSON và cột cuối cùng chứa JSON thực tế cho mỗi phần tử mảng.

Chúng tôi cũng có thể sử dụng sys.column chế độ xem danh mục hệ thống kiểm tra tên và loại cột của bảng.

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

Kết quả:

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

Một lần nữa, chính xác cách chúng tôi đã chỉ định nó.

Lưu ý rằng sys.columns luôn trả về max_length trong tổng số -1 khi kiểu dữ liệu cột là varchar (max) , nvarchar (tối đa) , varbinary (max) hoặc xml . Chúng tôi đã chỉ định nvarchar (tối đa) và vì vậy giá trị của -1 chính xác như mong đợi.

Cũng lưu ý rằng, khi bạn sử dụng AS JSON (như chúng tôi đã làm ở cột thứ tư), bạn phải đặt cột đó là nvarchar (max) .

Ví dụ 2 - CHÈN VÀO

Đây là ví dụ tương tự, ngoại trừ lần này chúng tôi chèn JSON vào một bảng đã tồn tại.

Do đó, điều đầu tiên chúng ta cần làm là tạo bảng:

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

Bây giờ chúng tôi đã tạo ra bảng đó, chúng tôi có thể tiếp tục và chèn nội dung của tài liệu JSON của chúng tôi vào bảng đó.

Như thế này:

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

Sự khác biệt duy nhất giữa ví dụ này và ví dụ trước là tôi đã thay thế bit sau:

SELECT * INTO JsonCats1

Với cái này:

INSERT INTO JsonCats2
SELECT * 

Vì vậy, việc chọn nội dung của bảng sẽ tạo ra kết quả giống như ví dụ trước.

SELECT * FROM JsonCats2;

Kết quả:

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

Ví dụ 3 - Sử dụng lược đồ mặc định

Trong các ví dụ trước, tôi đã xác định lược đồ của riêng mình. Đó là, tôi đã chỉ định tên của các cột cho các bảng và tôi đã chỉ định kiểu dữ liệu thực tế của các cột đó.

Nếu tôi chưa làm điều đó, OPENJSON() sẽ sử dụng lược đồ mặc định. Lược đồ mặc định bao gồm ba cột; phím , giá trị loại .

Dưới đây là một ví dụ về việc sử dụng lược đồ mặc định khi chèn JSON vào bảng.

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

Vì vậy, sự khác biệt duy nhất giữa ví dụ này và ví dụ đầu tiên, là tôi đã xóa toàn bộ WITH mệnh đề. Đó là bit xác định lược đồ trong hai ví dụ trước.

Bây giờ chúng ta hãy kiểm tra nội dung của bảng.

SELECT * FROM JsonCats3;

Kết quả:

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

Bảng này chứa ba cột như đã đề cập. Cột giá trị chứa từng phần tử mảng.

Ví dụ 4 - Sử dụng Khóa JSON làm Tiêu đề Cột

Ví dụ này là một chút giao thoa giữa hai ví dụ trước.

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

Chúng tôi vẫn đang xác định lược đồ của riêng mình, bởi vì chúng tôi đang sử dụng WITH mệnh đề. Nhưng bạn sẽ nhận thấy rằng tôi không ánh xạ tên cột với bất kỳ đường dẫn JSON nào. Điều này là do tôi đang sử dụng tên thực của các khóa JSON.

Khi bạn làm điều đó, OPENJSON() đủ thông minh để khớp tên cột của bạn với các khóa JSON.

Hãy xem những gì có trong bảng.

SELECT * FROM JsonCats4;

Kết quả:

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

Vì vậy, dữ liệu đã được chèn vào bảng, giống như trong hai ví dụ đầu tiên, nhưng lần này tên cột đã được lấy từ tài liệu JSON.

Ví dụ 5 - Chỉ định Ít cột hơn

Bạn không cần phải bao gồm tất cả các giá trị từ tài liệu JSON nếu bạn không cần tất cả chúng. Bạn chỉ có thể chỉ định những thứ bạn cần.

Bạn có thể làm điều này bằng cách chỉ định các cột trong SELECT danh sách.

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;

Kết quả:

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

Một cách khác để làm điều đó là xóa / s cột có liên quan khỏi WITH mệnh đề.

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;

Kết quả:

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

Mặc dù vậy, có lẽ tốt hơn nên làm cả hai.

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;

Kết quả:

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

Ví dụ 6 - Chỉ định Ít hàng hơn

Bạn cũng có thể sử dụng cú pháp T-SQL bình thường để lọc các hàng, để chỉ một số bản ghi được chèn vào bảng.

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;

Kết quả:

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

Trong trường hợp này, tôi đã sử dụng WHERE để chỉ chèn các hàng mà tôi quan tâm.

Nhập JSON từ tệp

Bạn có thể sử dụng OPENJSON() kết hợp với OPENROWSET() hàm nhập tệp JSON vào bảng.

Điều này cho phép bạn tải lên dữ liệu từ tệp JSON trên ổ đĩa cục bộ hoặc ổ đĩa mạng. Điều này giúp bạn không phải sao chép và dán nội dung của tài liệu vào mã SQL của mình. Điều này có thể đặc biệt có lợi khi làm việc với các tài liệu JSON lớn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cấu hình thông báo thư cơ sở dữ liệu trong MS SQL Server

  2. Cách ánh xạ nhiều phân vùng thành một nhóm tệp trong SQL Server (T-SQL)

  3. Chọn kích thước cơ sở dữ liệu SQL Server

  4. Truy vấn chỉ mục tạo lại máy chủ SQL

  5. Cách khắc phục “Chuyển đổi không thành công khi chuyển đổi giá trị thành kiểu dữ liệu” trong SQL Server