V MySQL, VALUES
příkaz vrátí sadu jednoho nebo více řádků jako tabulku. V podstatě se jedná o konstruktor hodnot tabulky v souladu se standardem SQL, který funguje také jako samostatný příkaz SQL.
VALUES
příkaz byl zaveden v MySQL 8.0.19.
Syntaxe
Oficiální syntaxe vypadá takto:
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
Příklad
Zde je jednoduchý příklad, který demonstruje, jak to funguje:
VALUES ROW(1, 2, 3), ROW(4, 5, 6);
Výsledek:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Výsledné sloupce jsou implicitně pojmenovány column_0
, column_1
, column_2
, a tak dále, vždy začínající 0
.
Vidíme, že každý ROW()
klauzule konstruktoru řádků má za následek nový řádek ve výsledné tabulce.
Každý ROW()
obsahuje seznam hodnot jedné nebo více skalárních hodnot uzavřených v závorkách. Hodnota může být doslovný údaj libovolného datového typu MySQL nebo výraz, který se převádí na skalární hodnotu.
Proto můžeme také provést následující:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");
Výsledek:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Nebo takové věci:
VALUES
ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));
Výsledek:
+---------------------+---------------------+ | 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
Ustanovení
Syntaxe umožňuje použití ORDER BY
klauzule za účelem uspořádání výsledků. Zjistil jsem však, že ORDER BY
klauzule nefunguje podle očekávání na systémech, na kterých jsem ji zkoušel spustit.
Zde je návod, jak by to mělo práce (podle dokumentace MySQL):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;
Výsledek:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | -2 | 3 | | 4 | 6 | 8 | | 5 | 7 | 9 | +----------+----------+----------+
Ale na dvou systémech, proti kterým jsem toto prohlášení spustil (MySQL 8.0.26 na Ubuntu 20.04.3 a MySQL 8.0.27 Homebrew na MacOS Monterery), ORDER BY
doložka vůbec nefunguje. Možná je to chyba.
LIMIT
Ustanovení
Můžeme použít LIMIT
klauzule k omezení počtu řádků, které jsou na výstupu:
VALUES
ROW('Black', 'Cat'),
ROW('Yellow', 'Dog'),
ROW('Aqua', 'Fish')
LIMIT 2;
Výsledek:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
S SELECT
Prohlášení
Můžeme také použít VALUES
příkaz v rámci SELECT
příkaz, jako by VALUES
konstruktor tabulky byly skutečnou tabulkou:
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;
Výsledek:
+---------+---------+ | PetName | PetType | +---------+---------+ | Bark | Dog | +---------+---------+
ROW()
Nesmí být prázdné
Konstruktor řádku nemůže být prázdný, pokud není použit jako zdroj v INSERT
prohlášení.
Zde je to, co se stane, když se pokusíme použít prázdný konstruktor řádku:
VALUES ROW();
Výsledek:
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()
Může obsahovat hodnoty Null
Přestože konstruktory řádků nemohou být prázdné, mohou obsahovat hodnoty Null:
VALUES ROW(null, null);
Výsledek:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | NULL | NULL | +----------+----------+
Každý ROW()
Musí obsahovat stejný počet hodnot
Každý ROW()
ve stejném VALUES
příkaz musí mít ve svém seznamu hodnot stejný počet hodnot.
Proto to nemůžeme udělat:
VALUES ROW(1, 2), ROW(3);
Výsledek:
ERROR 1136 (21S01): Column count doesn't match value count at row 2
Pomocí VALUES
vložit data
Můžeme použít VALUES
ve spojení s INSERT
a REPLACE
příkazy pro vložení dat do tabulky.
Příklad:
INSERT INTO Pets VALUES
ROW(9, 3, 1, 'Woof', '2020-10-03'),
ROW(10, 4, 5, 'Ears', '2022-01-11');
To vložilo dva řádky do tabulky s názvem Pets
. To předpokládá, že tabulka již existuje.
Nyní můžeme použít SELECT
příkaz k zobrazení nových hodnot v tabulce:
SELECT * FROM Pets
WHERE PetId IN (9, 10);
Výsledek:
+-------+-----------+---------+---------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | +-------+-----------+---------+---------+------------+ | 9 | 3 | 1 | Woof | 2020-10-03 | | 10 | 4 | 5 | Ears | 2022-01-11 | +-------+-----------+---------+---------+------------+
Výše uvedený INSERT
příkaz je ekvivalentem provedení následujícího:
INSERT INTO Pets VALUES
(9, 3, 1, 'Woof', '2020-10-03'),
(10, 4, 5, 'Ears', '2022-01-11');
Při vytváření tabulek
VALUES
příkaz lze také použít místo zdrojové tabulky v CREATE TABLE … SELECT
a CREATE VIEW … SELECT
prohlášení.
Zde je příklad:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;
Výsledek:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Můžeme také udělat toto:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;
Výsledek:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Tyto dva CREATE TABLE
prohlášení jsou jako toto:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;
Výsledek:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
V tomto případě jsem použil t2
tabulka jako zdrojová tabulka, namísto poskytování hodnot v VALUES
prohlášení.