W MySQL, VALUES
instrukcja zwraca zestaw jednego lub więcej wierszy w postaci tabeli. Zasadniczo jest to konstruktor wartości tabeli zgodny ze standardem SQL, który działa również jako samodzielna instrukcja SQL.
VALUES
oświadczenie zostało wprowadzone w MySQL 8.0.19.
Składnia
Oficjalna składnia wygląda następująco:
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
Przykład
Oto prosty przykład pokazujący, jak to działa:
VALUES ROW(1, 2, 3), ROW(4, 5, 6);
Wynik:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Otrzymane kolumny są niejawnie nazwane column_0
, column_1
, column_2
i tak dalej, zawsze zaczynając od 0
.
Widzimy, że każdy ROW()
Klauzula konstruktora wiersza powoduje utworzenie nowego wiersza w tabeli wynikowej.
Każdy ROW()
zawiera listę wartości zawierającą co najmniej jedną wartość skalarną ujętą w nawiasy. Wartość może być literałem dowolnego typu danych MySQL lub wyrażeniem, które przekłada się na wartość skalarną.
Dlatego możemy również wykonać następujące czynności:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");
Wynik:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Lub takie rzeczy:
VALUES
ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));
Wynik:
+---------------------+---------------------+ | 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
Klauzula
Składnia pozwala na użycie ORDER BY
klauzulę w celu uporządkowania wyników. Odkryłem jednak, że ORDER BY
klauzula nie działa zgodnie z oczekiwaniami na systemach, z którymi próbowałem go uruchomić.
Oto jak to powinno praca (zgodnie z dokumentacją MySQL):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;
Wynik:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | -2 | 3 | | 4 | 6 | 8 | | 5 | 7 | 9 | +----------+----------+----------+
Ale w dwóch systemach, na których uruchomiłem to oświadczenie (MySQL 8.0.26 na Ubuntu 20.04.3 i MySQL 8.0.27 Homebrew na MacOS Monterery), ORDER BY
klauzula w ogóle nie działa. Być może jest to błąd.
LIMIT
Klauzula
Możemy użyć LIMIT
klauzula ograniczająca liczbę wierszy, które są wyprowadzane:
VALUES
ROW('Black', 'Cat'),
ROW('Yellow', 'Dog'),
ROW('Aqua', 'Fish')
LIMIT 2;
Wynik:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Z SELECT
Oświadczenie
Możemy również użyć VALUES
instrukcja w SELECT
oświadczenie, tak jakby VALUES
konstruktor tabeli był rzeczywistą tabelą:
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;
Wynik:
+---------+---------+ | PetName | PetType | +---------+---------+ | Bark | Dog | +---------+---------+
ROW()
Nie może być pusty
Konstruktor wiersza nie może być pusty, chyba że jest używany jako źródło w INSERT
oświadczenie.
Oto, co się stanie, jeśli spróbujemy użyć konstruktora pustych wierszy:
VALUES ROW();
Wynik:
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()
Może zawierać wartości zerowe
Chociaż konstruktory wierszy nie mogą być puste, mogą zawierać wartości Null:
VALUES ROW(null, null);
Wynik:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | NULL | NULL | +----------+----------+
Każdy ROW()
Musi zawierać tę samą liczbę wartości
Każdy ROW()
w tych samych VALUES
instrukcja musi mieć taką samą liczbę wartości na swojej liście wartości.
Dlatego nie możemy tego zrobić:
VALUES ROW(1, 2), ROW(3);
Wynik:
ERROR 1136 (21S01): Column count doesn't match value count at row 2
Korzystanie z VALUES
wstawić dane
Możemy użyć VALUES
instrukcja w połączeniu z INSERT
i REPLACE
instrukcje wstawiania danych do tabeli.
Przykład:
INSERT INTO Pets VALUES
ROW(9, 3, 1, 'Woof', '2020-10-03'),
ROW(10, 4, 5, 'Ears', '2022-01-11');
To wstawiło dwa wiersze do tabeli o nazwie Pets
. Zakłada się, że tabela już istnieje.
Możemy teraz użyć SELECT
oświadczenie, aby zobaczyć nowe wartości w tabeli:
SELECT * FROM Pets
WHERE PetId IN (9, 10);
Wynik:
+-------+-----------+---------+---------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | +-------+-----------+---------+---------+------------+ | 9 | 3 | 1 | Woof | 2020-10-03 | | 10 | 4 | 5 | Ears | 2022-01-11 | +-------+-----------+---------+---------+------------+
Powyższy INSERT
oświadczenie jest równoznaczne z wykonaniem następujących czynności:
INSERT INTO Pets VALUES
(9, 3, 1, 'Woof', '2020-10-03'),
(10, 4, 5, 'Ears', '2022-01-11');
Podczas tworzenia tabel
VALUES
instrukcja może być również użyta zamiast tabeli źródłowej w CREATE TABLE … SELECT
i CREATE VIEW … SELECT
oświadczenia.
Oto przykład:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;
Wynik:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Możemy również to zrobić:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;
Wynik:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Te dwa CREATE TABLE
oświadczenia są jak robienie tego:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;
Wynik:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
W tym przypadku użyłem t2
tabeli jako tabeli źródłowej, zamiast podawać wartości w VALUES
oświadczenie.