Search the MySQL manual:
Subscribe to the monthly
MySQL Newsletter!

6.4.3 Синтаксис оператора INSERT

    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...),(...),...
        [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]
или INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
или INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name
        SET col_name=(expression | DEFAULT), ...
        [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]

Оператор INSERT вставляет новые строки в существующую таблицу. Форма данной команды INSERT ... VALUES вставляет строки в соответствии с точно указанными в команде значениями. Форма INSERT ... SELECT вставляет строки, выбранные из другой таблицы или таблиц. Форма INSERT ... VALUES со списком из нескольких значений поддерживается в версии MySQL 3.22.5 и более поздних. Синтаксис выражения col_name=expression поддерживается в версии MySQL 3.22.10 и более поздних.

tbl_name задает таблицу, в которую должны быть внесены строки. Столбцы, для которых заданы величины в команде, указываются в списке имен столбцов или в части SET:

Если задается команда INSERT ... SELECT или INSERT ... VALUES со списками из нескольких значений, то для получения информации о данном запросе можно использовать функцию C API mysql_info(). Формат этой информационной строки приведен ниже:

Records: 100 Duplicates: 0 Warnings: 0

Duplicates показывает число строк, которые не могли быть внесены, поскольку они дублировали бы значения некоторых существующих уникальных индексов. Указатель Warnings показывает число попыток внести величину в столбец, который по какой-либо причине оказался проблематичным. Предупреждения возникают при выполнении любого из следующих условий:

Главы

User Comments

Posted by Marty Alchin on December 18 2002 5:27pm[Delete] [Edit]

This page states that you can use a previously
inserted column to help define a new column, in its
example. However, it seems that auto_increment
columns aren't defined until after the rest of the
query is evaluated. This makes sense, as it wouldn't
assign an auto_increment value until the parser has
verified that the query is valid, but it means that you
can't use an auto_increment column to help define
subsequent columns. For example:

INSERT INTO `table` (id,sentence) VALUES(NULL,
concat('The id is ',id))

Even though the id column is listed first and is
evaluated first, a value is not inserted into it until the
rest of the query is evaluated, so the sentence
column would always contain the string 'The id is 0'.

Posted by Joshua Mostafa on November 13 2002 9:17pm[Delete] [Edit]

Regarding the use of reserved words in table names:
much better than the use of backticks is the
complete avoidance of reserved word usage. The
same goes for spaces in table names (another
scenario which calls for the use of backticks):
generally a bad idea, especially when the use of
backticks could cause potentially cause collision with
their use in scripting language, eg the execution
operator in Perl or PHP (the backtick).

Posted by Martin Francis on March 12 2003 7:12am[Delete] [Edit]

*****************
* COPY A RECORD *
*****************
Ever wanted to copy a table record within
the same table?
Here's how to create a new copy of an existing
record for any kind of table, regardless of the
number of columns or their type.
In this example we have a table called `media` with
a number of fields which we want to duplicate, and
one, ID, containing a unique ID which must
change.
On entry to the PHP (or other language) routine we
know the ID of the record we want to copy
($oldID), and we have generated another ID for the
new record ($newID).

1) Create a TEMPORARY table named
by combining the ID of the record we are to copy
($oldID) and the name of the table. This prevents
collisions if two people are doing the same kind of
thing at the
same time. This new table is populated by the
combined SELECT statement.

2) UPDATE any fields you wish to edit in the
temporary table (in my case, just the field called ID)

3) INSERT the modified record from the new table
back into the old - there's no need to
specify 'WHERE' since this table contains just the one
record we were working with.

4) Drop the old table.

Code:
CREATE TEMPORARY TABLE `media_$oldID`
SELECT * FROM `media`
WHERE ID = '$oldID';

UPDATE `media_$oldID`
SET ID = '$newID';

INSERT INTO `media`
SELECT * FROM `media_$oldID`;

DROP TABLE `media_$oldID`;

Benchmarks:
To create 100 copies of a 360KB media record
(36MB data):
* Windows 98 / PHP / Apache = 20 seconds
* Linux / PHP / Apache (shared hosting server) = 231 seconds - in retrospect, it's probably not a
good idea to performance test a shared web server
without permission ;)

Hope this is of use to someone.

Posted by [name withheld] on December 18 2002 5:29pm[Delete] [Edit]

Error 1036 Table tbl_name is read only.
Here is a new one for all you who have recieved this
error running MySql as a service on windows 2000.
When running the MySql server --standalone all
tables work fine, but when installed as a service all
the tables become read-only? After many hours of
troubleshooting i relized when i decided to reload
MySql and tried to DROP a database, that MySql did
not have file write permission to the hard drive under
Win2000. The FIX: go to
start=>programs=>administrative tools=>services
and go to properties of the MySql service (once
installed) select the log-on tab and choose "Log on
as this account: and put in the administrator log-on
information (or a user with file write permissions).
The Local System Account apperentlydoes not seem
to have that permission. Anyway it worked for me if
you should have this problem give it a try.

Posted by [name withheld] on March 7 2003 1:41pm[Delete] [Edit]

maybe running a service such as mysql as administrator isn't the best idea in the world, just an opinion (theres a reason it won't run as root generally in linux ;) )

Posted by Yakov on July 8 2003 8:08am[Delete] [Edit]

To insert special characters, like the "apostrophe" read the section on string syntax: http://www.mysql.com/doc/en/String_syntax.html

Here's an example:
insert into Citylist (cityname) VALUES ('St. John\'s')


Posted by Matthew Loff on July 21 2003 1:34pm[Delete] [Edit]

The INSERT ... ON DUPLICATE KEY UPDATE feature is handy, but if you're not ready to upgrade to an non-production version (as is my case), you -may- be able to use REPLACE to accomplish the same thing (based on your code and key usage, of course).

REPLACE is in close proximity to this topic in the manual, but it was a long time before I realized this alternative.

Posted by Steve Lawrence on August 25 2003 1:39pm[Delete] [Edit]

Be warned of the difference between The INSERT ... ON DUPLICATE KEY UPDATE and REPLACE.

Replace actually deletes the matching row before doing an insert. It appears DUPLICATE KEY UPDATE actually does an update.

This means all data from the row will have to be inserted, you cannot update only one column from a row with REPLACE.

Posted by Henrik SchrЖder on February 8 2004 10:02am[Delete] [Edit]

Martin Francis:

Uh, you *could* do it like that, but why not use the INSERT INTO ... SELECT ... syntax instead? Like this:

INSERT INTO table1 (id_col, col1, col2, col3, ...) SELECT 'new_id', col1, col2, col3, ... FROM table1 WHERE id_col = 'old_id';

One statement, no temp tables. I'm sure your solution works, but it seems kinda convoluted, don't you think?

Posted by Shelley Nina on March 4 2004 9:49am[Delete] [Edit]

I was looking for a way to store millions of thumbnail preview images that I downloaded for free from http://www.thumbshots.com and http://www.thumbshots.org web sites. Because they are binary pictures, you need to encode them before inserting into database. One way in PHP is to use the base64_encode function. Encoded graphic is about 30% bigger so make sure to size your columns accordingly.

$Image = base64_encode($RawImage);

then you can insert into a normal varchar column:

INSERT INTO visual (id, image) VALUES (1, '$Image')

To read back the image, you need to decode it first:

SELECT image FROM visual WHERE id = 1

$RawImage = base64_decode($Image);

MySQL is very fast, easy and efficient at storing varchar data types, blobs are less portable between other databases.

Posted by Bob Terrell on March 4 2004 4:21pm[Delete] [Edit]

Regarding Shelley Nina's comment...

If you're going to be using MySQL (or any database) to keep track of images, you should consider putting the images in a folder (or folders) and storing the path to the image in the database instead, especially if the image is to be used in a web context.

Among other conveniences, this will eliminate the 30% overhead she mentioned. It will also probably be faster for the client and server, and is probably a very good idea if the image is frequently accessed.

Add your own comment.