In MySQL, i VALUES istruzione restituisce un insieme di una o più righe come tabella. Fondamentalmente, è un costruttore di valori di tabella in conformità con lo standard SQL, che funziona anche come un'istruzione SQL autonoma.
I VALUES istruzione è stata introdotta in MySQL 8.0.19.
Sintassi
La sintassi ufficiale è questa:
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 Esempio
Ecco un semplice esempio per dimostrare come funziona:
VALUES ROW(1, 2, 3), ROW(4, 5, 6); Risultato:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Le colonne risultanti sono implicitamente denominate column_0 , column_1 , column_2 , e così via, iniziando sempre con 0 .
Possiamo vedere che ogni ROW() La clausola del costruttore di riga genera una nuova riga nella tabella risultante.
Ogni ROW() contiene un elenco di valori di uno o più valori scalari racchiusi tra parentesi. Un valore può essere un valore letterale di qualsiasi tipo di dati MySQL o un'espressione che si risolve in un valore scalare.
Pertanto possiamo anche fare quanto segue:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog"); Risultato:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
O cose come questa:
VALUES
ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR)); Risultato:
+---------------------+---------------------+ | 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 | +---------------------+---------------------+
Il ORDER BY Clausola
La sintassi consente l'utilizzo di ORDER BY clausola per ordinare i risultati. Tuttavia, ho scoperto che il ORDER BY La clausola non funziona come previsto sui sistemi su cui ho provato a eseguirla.
Ecco come dovrebbe lavoro (secondo la documentazione MySQL):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1; Risultato:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | -2 | 3 | | 4 | 6 | 8 | | 5 | 7 | 9 | +----------+----------+----------+
Ma sui due sistemi su cui ho eseguito quell'istruzione (MySQL 8.0.26 su Ubuntu 20.04.3 e MySQL 8.0.27 Homebrew su MacOS Monterery), il ORDER BY la clausola non funziona affatto. Forse questo è un bug.
Il LIMIT Clausola
Possiamo usare il LIMIT clausola per limitare il numero di righe che vengono emesse:
VALUES
ROW('Black', 'Cat'),
ROW('Yellow', 'Dog'),
ROW('Aqua', 'Fish')
LIMIT 2; Risultato:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Con un SELECT Dichiarazione
Possiamo anche usare i VALUES istruzione all'interno di un SELECT istruzione, come se il VALUES costruttore di tabelle erano una tabella reale:
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; Risultato:
+---------+---------+ | PetName | PetType | +---------+---------+ | Bark | Dog | +---------+---------+
ROW() Non può essere vuoto
Un costruttore di riga non può essere vuoto, a meno che non venga utilizzato come origine in un INSERT dichiarazione.
Ecco cosa succede se proviamo a utilizzare un costruttore di righe vuoto:
VALUES ROW(); Risultato:
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() Può contenere valori nulli
Sebbene i costruttori di riga non possano essere vuoti, possono contenere valori Null:
VALUES ROW(null, null); Risultato:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | NULL | NULL | +----------+----------+
Ogni ROW() Deve contenere lo stesso numero di valori
Ogni ROW() nello stesso VALUES l'istruzione deve avere lo stesso numero di valori nella sua lista valori.
Pertanto, non possiamo farlo:
VALUES ROW(1, 2), ROW(3); Risultato:
ERROR 1136 (21S01): Column count doesn't match value count at row 2
Utilizzo di VALUES per inserire dati
Possiamo usare i VALUES istruzione insieme a INSERT e REPLACE istruzioni per inserire dati in una tabella.
Esempio:
INSERT INTO Pets VALUES
ROW(9, 3, 1, 'Woof', '2020-10-03'),
ROW(10, 4, 5, 'Ears', '2022-01-11');
Che ha inserito due righe in una tabella chiamata Pets . Ciò presuppone che la tabella esista già.
Ora possiamo usare un SELECT istruzione per vedere i nuovi valori nella tabella:
SELECT * FROM Pets
WHERE PetId IN (9, 10); Risultato:
+-------+-----------+---------+---------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | +-------+-----------+---------+---------+------------+ | 9 | 3 | 1 | Woof | 2020-10-03 | | 10 | 4 | 5 | Ears | 2022-01-11 | +-------+-----------+---------+---------+------------+
Quanto sopra INSERT istruzione equivale a fare quanto segue:
INSERT INTO Pets VALUES
(9, 3, 1, 'Woof', '2020-10-03'),
(10, 4, 5, 'Ears', '2022-01-11'); Quando si creano tabelle
I VALUES l'istruzione può essere utilizzata anche al posto della tabella di origine in CREATE TABLE … SELECT e CREATE VIEW … SELECT dichiarazioni.
Ecco un esempio:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1; Risultato:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Possiamo anche fare questo:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2; Risultato:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Quei due CREATE TABLE le dichiarazioni sono come fare questo:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3; Risultato:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
In questo caso, ho usato il t2 table come tabella di origine, invece di fornire i valori in un VALUES dichiarazione.