MySQL
FÖRA IN
Sök…
Syntax
INSERT [LOW_PRIORITY | Fördröjd | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name, ...)] [(col_name, ...)] {VALUES | VALUE} ({expr | DEFAULT}, ...), (...), ... [ON DUPLICATE KEY UPDATE col_name = expr [, col_name = expr] ...]
INSERT [LOW_PRIORITY | Fördröjd | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name, ...)] SET col_name = {expr | DEFAULT}, ... [ON DUPLICATE KEY UPDATE col_name = expr [, col_name = expr] ...]
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name, ...)] [(col_name, ...)] SELECT ... [ON DUPLICATE KEY UPDATE col_name = expr [, col_name = expr] ...]
Ett uttryck expr kan hänvisa till valfri kolumn som har ställts in tidigare i en värdelista. Du kan till exempel göra detta eftersom värdet för col2 avser col1, som tidigare har tilldelats:
INSERT IN tbl_name (col1, col2) VÄRDER (15, col1 * 2);INSERT-satser som använder VALUES-syntax kan infoga flera rader. För att göra detta, inkludera flera listor med kolumnvärden, var och en innesluten inom parentes och separerad med kommatecken. Exempel:
INSERT IN tbl_name (a, b, c) VÄRDER (1,2,3), (4,5,6), (7,8,9);Värdelistan för varje rad måste bifogas inom parentes. Följande uttalande är olagligt eftersom antalet värden i listan inte stämmer med antalet kolumnnamn:
INSERT IN tbl_name (a, b, c) VÄRDER (1,2,3,4,5,6,7,8,9);INSERT ... VÄLJ Syntax
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name, ...)] [(col_name, ...)] VÄLJ ... [ON DUPLICATE KEY UPDATE col_name = expr, ...]Med INSERT ... SELECT kan du snabbt sätta in många rader i ett bord från ett eller många tabeller. Till exempel:
INSERT IN tbl_temp2 (fld_id) VÄLJ tbl_temp1.fld_order_id FRÅN tbl_temp1 VAR tbl_temp1.fld_order_id> 100;
Anmärkningar
Grundläggande infoga
INSERT INTO `table_name` (`field_one`, `field_two`) VALUES ('value_one', 'value_two');
I detta triviala exempel är table_name
där data ska läggas till, field_one
och field_two
är fält att ställa in data mot, och value_one
och value_two
är data som ska göras mot field_one
respektive field_two
.
Det är god praxis att lista de fält du sätter in data i din kod, som om tabellen ändras och nya kolumner läggs till, ditt infog skulle bryta om de inte skulle vara där
INSERT, PÅ DUPLIKAT UPPDATERING
INSERT INTO `table_name`
(`index_field`, `other_field_1`, `other_field_2`)
VALUES
('index_value', 'insert_value', 'other_value')
ON DUPLICATE KEY UPDATE
`other_field_1` = 'update_value',
`other_field_2` = VALUES(`other_field_2`);
Detta INSERT
de angivna värdena i table_name
, men om den unika nyckeln redan finns uppdateras den other_field_1
att få ett nytt värde.
Ibland, när det uppdateras på duplikatnyckeln, är det praktiskt att använda VALUES()
för att få åtkomst till det ursprungliga värdet som skickades till INSERT
istället för att ställa in värdet direkt. På detta sätt kan du ställa in olika värden med INSERT
och UPDATE
. Se exemplet ovan där other_field_1
är inställd på insert_value
på INSERT
eller att update_value
på UPDATE
medan other_field_2
alltid är inställd på other_value
.
Det avgörande för att Insert on Duplicate Key Update (IODKU) ska fungera är schemat som innehåller en unik nyckel som kommer att signalera en duplikatkollision. Den unika nyckeln kan vara en primär nyckel eller inte. Det kan vara en unik nyckel på en enda kolumn eller en flerspelare (sammansatt nyckel).
Infoga flera rader
INSERT INTO `my_table` (`field_1`, `field_2`) VALUES
('data_1', 'data_2'),
('data_1', 'data_3'),
('data_4', 'data_5');
Detta är ett enkelt sätt att lägga till flera rader samtidigt med ett INSERT
uttalande.
Den här typen av "batch" -insats är mycket snabbare än att sätta in rader en efter en. Vanligtvis är det att sätta in 100 rader i en enda satsinsats på detta sätt 10 gånger så snabbt som att sätta in dem alla individuellt.
Ignorerar befintliga rader
Vid import av stora datasätt kan det under vissa omständigheter vara att föredra att hoppa över rader som vanligtvis skulle orsaka att frågan misslyckas på grund av en kolumnbehållning, t.ex. duplicerade primärnycklar. Detta kan göras med INSERT IGNORE
.
Överväg följande exempeldatabas:
SELECT * FROM `people`;
--- Produces:
+----+------+
| id | name |
+----+------+
| 1 | john |
| 2 | anna |
+----+------+
INSERT IGNORE INTO `people` (`id`, `name`) VALUES
('2', 'anna'), --- Without the IGNORE keyword, this record would produce an error
('3', 'mike');
SELECT * FROM `people`;
--- Produces:
+----+--------+
| id | name |
+----+--------+
| 1 | john |
| 2 | anna |
| 3 | mike |
+----+--------+
Det viktiga att komma ihåg är att INSERT IGNORE också tyst kommer att hoppa över andra fel, här är vad Mysql officiella dokumentationer säger:
Datakonvertering som skulle utlösa fel avbryter uttalandet om IGNORE inte är> specificerat. Med IGNORE justeras ogiltiga värden till de närmaste värdena och> infogas; varningar produceras men uttalandet avbryts inte.
Obs: - Avsnittet nedan läggs till för fullständighetens skull, men anses inte vara bästa praxis (detta skulle t.ex. misslyckas om en annan kolumn läggs till i tabellen).
Om du anger värdet för motsvarande kolumn för alla kolumner i tabellen kan du ignorera INSERT
i INSERT
satsen enligt följande:
INSERT INTO `my_table` VALUES
('data_1', 'data_2'),
('data_1', 'data_3'),
('data_4', 'data_5');
INSERT SELECT (Infoga data från en annan tabell)
Detta är det grundläggande sättet att infoga data från en annan tabell med SELECT-uttalandet.
INSERT INTO `tableA` (`field_one`, `field_two`)
SELECT `tableB`.`field_one`, `tableB`.`field_two`
FROM `tableB`
WHERE `tableB`.clmn <> 'someValue'
ORDER BY `tableB`.`sorting_clmn`;
Du kan SELECT * FROM
, men då tableA
och tableB
måste ha matchande kolumnen räkna och motsvarande datatyper.
Kolumner med AUTO_INCREMENT
behandlas som i INSERT
med VALUES
klausulen.
Denna syntax gör det enkelt att fylla (tillfälliga) tabeller med data från andra tabeller, ännu mer när data ska filtreras på insatsen.
INSERT med AUTO_INCREMENT + LAST_INSERT_ID ()
När en tabell har en AUTO_INCREMENT
PRIMARY KEY
, sätter man normalt inte in den kolumnen. Ange istället alla andra kolumner och fråga sedan vad den nya iden var.
CREATE TABLE t (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL,
this ...,
that ...,
PRIMARY KEY(id) );
INSERT INTO t (this, that) VALUES (..., ...);
SELECT LAST_INSERT_ID() INTO @id;
INSERT INTO another_table (..., t_id, ...) VALUES (..., @id, ...);
Observera att LAST_INSERT_ID()
är knuten till sessionen, så även om flera anslutningar sätts in i samma tabell får alla sina egna ID.
Din klient-API har förmodligen ett alternativt sätt att få LAST_INSERT_ID()
utan att faktiskt utföra ett SELECT
och överlämna värdet till klienten istället för att lämna det i ett @variable
i MySQL. Sådant är vanligtvis att föredra.
Längre, mer detaljerat exempel
Den "normala" användningen av IODKU är att utlösa "duplikatnyckel" baserad på någon UNIQUE
nyckel, inte AUTO_INCREMENT PRIMARY KEY
. Följande demonstrerar sådant. Observera att den inte tillhandahåller id
i INSERT.
Konfigurera följande exempel:
CREATE TABLE iodku (
id INT AUTO_INCREMENT NOT NULL,
name VARCHAR(99) NOT NULL,
misc INT NOT NULL,
PRIMARY KEY(id),
UNIQUE(name)
) ENGINE=InnoDB;
INSERT INTO iodku (name, misc)
VALUES
('Leslie', 123),
('Sally', 456);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 456 |
+----+--------+------+
Fallet med IODKU som utför en "uppdatering" och LAST_INSERT_ID()
hämtar relevant id
:
INSERT INTO iodku (name, misc)
VALUES
('Sally', 3333) -- should update
ON DUPLICATE KEY UPDATE -- `name` will trigger "duplicate key"
id = LAST_INSERT_ID(id),
misc = VALUES(misc);
SELECT LAST_INSERT_ID(); -- picking up existing value
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
Fallet där IODKU utför en "insert" och LAST_INSERT_ID()
hämtar den nya id
:
INSERT INTO iodku (name, misc)
VALUES
('Dana', 789) -- Should insert
ON DUPLICATE KEY UPDATE
id = LAST_INSERT_ID(id),
misc = VALUES(misc);
SELECT LAST_INSERT_ID(); -- picking up new value
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 3 |
+------------------+
Resultatet av tabellinnehållet:
SELECT * FROM iodku;
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 3333 | -- IODKU changed this
| 3 | Dana | 789 | -- IODKU added this
+----+--------+------+
Förlorade AUTO_INCREMENT-id
Flera "infoga" -funktioner kan "bränna" id. Här är ett exempel som använder InnoDB (andra motorer kan fungera annorlunda):
CREATE TABLE Burn (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL,
name VARCHAR(99) NOT NULL,
PRIMARY KEY(id),
UNIQUE(name)
) ENGINE=InnoDB;
INSERT IGNORE INTO Burn (name) VALUES ('first'), ('second');
SELECT LAST_INSERT_ID(); -- 1
SELECT * FROM Burn ORDER BY id;
+----+--------+
| 1 | first |
| 2 | second |
+----+--------+
INSERT IGNORE INTO Burn (name) VALUES ('second'); -- dup 'IGNOREd', but id=3 is burned
SELECT LAST_INSERT_ID(); -- Still "1" -- can't trust in this situation
SELECT * FROM Burn ORDER BY id;
+----+--------+
| 1 | first |
| 2 | second |
+----+--------+
INSERT IGNORE INTO Burn (name) VALUES ('third');
SELECT LAST_INSERT_ID(); -- now "4"
SELECT * FROM Burn ORDER BY id; -- note that id=3 was skipped over
+----+--------+
| 1 | first |
| 2 | second |
| 4 | third | -- notice that id=3 has been 'burned'
+----+--------+
Tänk på det (ungefär) på detta sätt: Först ser inlägget för att se hur många rader som kan sättas in. Ta sedan så många värden från auto_inkrementet för den tabellen. Slutligen sätter i raderna, använd ids efter behov och bränna eventuella rester.
Den enda gången resterna kan återvinnas är om systemet stängs av och startas om. Vid omstart utförs effektivt MAX(id)
. Detta kan återanvända id: er som bränns eller som frigjorts av DELETEs
av den högsta ID: n.
I huvudsak varje smak av INSERT
(inklusive REPLACE
, som är DELETE
+ INSERT
) kan bränna id. I InnoDB kan den globala (inte session!) Variabeln innodb_autoinc_lock_mode
användas för att kontrollera en del av vad som händer.
När du "normaliserar" långa strängar till ett AUTO INCREMENT id
kan bränning lätt ske. Detta kan leda till överflödet av den INT
du valde.