Trong MySQL, VALUES
câu lệnh trả về một tập hợp một hoặc nhiều hàng dưới dạng một bảng. Về cơ bản, nó là một hàm tạo giá trị bảng phù hợp với tiêu chuẩn SQL, cũng hoạt động như một câu lệnh SQL độc lập.
VALUES
câu lệnh đã được giới thiệu trong MySQL 8.0.19.
Cú pháp
Cú pháp chính thức như sau:
VALUES row_constructor_list [ORDER BY column_designator] [LIMIT number]
row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]
value_list:
value[, value][, ...]
column_designator:
column_index
Ví dụ
Dưới đây là một ví dụ đơn giản để chứng minh cách nó hoạt động:
VALUES ROW(1, 2, 3), ROW(4, 5, 6);
Kết quả:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Các cột kết quả được đặt tên ngầm định là column_0
, column_1
, column_2
, v.v., luôn bắt đầu bằng 0
.
Chúng ta có thể thấy rằng mỗi ROW()
mệnh đề hàm tạo hàng dẫn đến một hàng mới trong bảng kết quả.
Mỗi ROW()
chứa một danh sách giá trị của một hoặc nhiều giá trị vô hướng được đặt trong dấu ngoặc đơn. Giá trị có thể là một ký tự của bất kỳ kiểu dữ liệu MySQL nào hoặc một biểu thức phân giải thành giá trị vô hướng.
Do đó, chúng tôi cũng có thể làm như sau:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");
Kết quả:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Hoặc những thứ như thế này:
VALUES
ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));
Kết quả:
+---------------------+---------------------+ | column_0 | column_1 | +---------------------+---------------------+ | 2022-02-17 00:00:00 | 2032-02-17 00:00:00 | | 2022-02-17 09:30:46 | 2022-02-17 11:30:46 | +---------------------+---------------------+
ORDER BY
Mệnh đề
Cú pháp cho phép sử dụng ORDER BY
mệnh đề để sắp xếp các kết quả. Tuy nhiên, tôi nhận thấy rằng ORDER BY
điều khoản không hoạt động như mong đợi trên các hệ thống mà tôi đã thử chạy nó.
Đây là cách nó nên làm việc (theo tài liệu MySQL):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;
Kết quả:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | -2 | 3 | | 4 | 6 | 8 | | 5 | 7 | 9 | +----------+----------+----------+
Nhưng trên hai hệ thống mà tôi đã chạy câu lệnh đó (MySQL 8.0.26 trên Ubuntu 20.04.3 và MySQL 8.0.27 Homebrew trên MacOS Monterery), ORDER BY
mệnh đề hoàn toàn không hoạt động. Có lẽ đây là một lỗi.
LIMIT
Mệnh đề
Chúng tôi có thể sử dụng LIMIT
mệnh đề giới hạn số hàng được xuất:
VALUES
ROW('Black', 'Cat'),
ROW('Yellow', 'Dog'),
ROW('Aqua', 'Fish')
LIMIT 2;
Kết quả:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Với SELECT
Tuyên bố
Chúng tôi cũng có thể sử dụng VALUES
câu lệnh trong SELECT
tuyên bố, như thể VALUES
hàm tạo bảng là một bảng thực tế:
SELECT
PetName,
PetType
FROM
(VALUES
ROW(1, "Fluffy", "Cat"),
ROW(2, "Bark", "Dog"),
ROW(3, "Gallop", "Horse")
) AS Pets(PetId, PetName, PetType)
WHERE PetId = 2;
Kết quả:
+---------+---------+ | PetName | PetType | +---------+---------+ | Bark | Dog | +---------+---------+
ROW()
Không được để trống
Một hàm tạo hàng không được để trống, trừ khi nó được sử dụng làm nguồn trong INSERT
tuyên bố.
Dưới đây là những gì sẽ xảy ra nếu chúng tôi cố gắng sử dụng một hàm tạo hàng trống:
VALUES ROW();
Kết quả:
ERROR 3942 (HY000): Each row of a VALUES clause must have at least one column, unless when used as source in an INSERT statement.
ROW()
Có thể chứa giá trị rỗng
Mặc dù các hàm tạo hàng không được để trống, nhưng chúng có thể chứa các giá trị Null:
VALUES ROW(null, null);
Kết quả:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | NULL | NULL | +----------+----------+
Mỗi ROW()
Phải chứa cùng một số giá trị
Mỗi ROW()
trong cùng một VALUES
câu lệnh phải có cùng số lượng giá trị trong danh sách giá trị của nó.
Do đó, chúng tôi không thể làm điều này:
VALUES ROW(1, 2), ROW(3);
Kết quả:
ERROR 1136 (21S01): Column count doesn't match value count at row 2
Sử dụng VALUES
để Chèn dữ liệu
Chúng ta có thể sử dụng VALUES
câu lệnh kết hợp với INSERT
và REPLACE
câu lệnh để chèn dữ liệu vào bảng.
Ví dụ:
INSERT INTO Pets VALUES
ROW(9, 3, 1, 'Woof', '2020-10-03'),
ROW(10, 4, 5, 'Ears', '2022-01-11');
Điều đó đã chèn hai hàng vào một bảng có tên là Pets
. Điều này giả định rằng bảng đã tồn tại.
Bây giờ chúng ta có thể sử dụng SELECT
để xem các giá trị mới trong bảng:
SELECT * FROM Pets
WHERE PetId IN (9, 10);
Kết quả:
+-------+-----------+---------+---------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | +-------+-----------+---------+---------+------------+ | 9 | 3 | 1 | Woof | 2020-10-03 | | 10 | 4 | 5 | Ears | 2022-01-11 | +-------+-----------+---------+---------+------------+
INSERT
ở trên câu lệnh tương đương với việc làm như sau:
INSERT INTO Pets VALUES
(9, 3, 1, 'Woof', '2020-10-03'),
(10, 4, 5, 'Ears', '2022-01-11');
Khi tạo bảng
VALUES
câu lệnh cũng có thể được sử dụng thay cho bảng nguồn trong CREATE TABLE … SELECT
và CREATE VIEW … SELECT
tuyên bố.
Đây là một ví dụ:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;
Kết quả:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Chúng tôi cũng có thể làm điều này:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;
Kết quả:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Hai CREATE TABLE
đó các câu lệnh như thế này:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;
Kết quả:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Trong trường hợp này, tôi đã sử dụng t2
bảng dưới dạng bảng nguồn, thay vì cung cấp các giá trị trong VALUES
tuyên bố.