SELECT
HANDLER
INSERT
INSERT DELAYED
UPDATE
DELETE
TRUNCATE
REPLACE
LOAD DATA INFILE
DO
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 ... VALUES
или INSERT ...
SELECT
, то величины для всех столбцов должны быть определены в списке
VALUES()
или в результате работы SELECT
. Если порядок столбцов в
таблице неизвестен, для его получения можно использовать DESCRIBE tbl_name
.
CREATE TABLE
.
Вы также можете использовать ключевое слово DEFAULT
для того, чтобы
установить столбец в его значение по умолчанию (новшество в MySQL 4.0.3). Это
облегчает написание INSERT
, присвающим значения всем, за исключением
одного-двух, столбцам, т.к. такой ситнаксис позволяет вам обойтись без указания
списка столбцов, которые оператор INSERT
должен обновить.
В MySQL всегда предусмотрено значение по умолчанию для каждого поля. Это
требование ``навязано'' MySQL, чтобы обеспечить возможность работы как с
таблицами, поддерживающими транзакции, так и с таблицами, не поддерживающими
их.
Наша точка зрения (разработчиков) состоит в том, что проверка содержимого полей
должна производиться приложением, а не сервером баз данных.
expression
может относится к любому столбцу, который ранее
был внесен в список значений. Например, можно указать следующее:
mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);Но нельзя указать:
mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
LOW_PRIORITY
, то выполнение данной
команды INSERT
будет задержано до тех пор, пока другие клиенты не
завершат чтение этой таблицы. В этом случае данный клиент должен
ожидать, пока данная команда вставки не будет завершена, что в случае
интенсивного использования таблицы может потребовать значительного
времени. В противоположность этому команда INSERT DELAYED
позволяет
данному клиенту продолжать операцию сразу же. See section 6.4.4 Синтаксис оператора INSERT DELAYED
.
Следует отметить, что указатель LOW_PRIORITY
обычно не
используется с таблицами MyISAM
, поскольку при его указании становятся
невозможными параллельные вставки. See section 7.1 Таблицы MyISAM
.
INSERT
со строками, имеющими много значений,
указывается ключевое слово IGNORE
, то все строки, имеющие
дублирующиеся ключи PRIMARY
или UNIQUE
в этой таблице, будут
проигнорированы и не будут внесены. Если не указывать IGNORE
, то
данная операция вставки прекращается при обнаружении строки, имеющей
дублирующееся значение существующего ключа. Количество строк,
внесенных в данную таблицу, можно определить при помощи функции C API
mysql_info()
.
ON DUPLICATE KEY UPDATE
(новшество в MySQL 4.1.0),
и производится вставка строки, которая вызывает ошибку дублирующегося первичного (PRIMARY
) или
уникального (UNIQUE
) ключа, то вполняется UPDATE
старой строки.
Например:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) --> ON DUPLICATE KEY UPDATE c=c+1;Если
a
определяется как UNIQUE
и уже содержит 1
, то тогда
вышеуказанная команда будет аналогична следующей:
mysql> UPDATE table SET c=c+1 WHERE a=1;Внимание: если столбец
b
также является уникальным ключем, то
UPDATE
переписывается как:
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;и если несколько записей соответствуют
a=1 OR b=2
только одна запись
будет обновлена! В общем случае, следует избегать использования ON DUPLICATE KEY
на таблицах со множеством уникальных (UNIQUE
) ключей.
Когда используется ON DUPLICATE KEY UPDATE
,
опция DELAYED
будет проигнорирована.
DONT_USE_DEFAULT_FIELDS
, то команда INSERT
будет генерировать ошибку,
если явно не указать величины для всех столбцов, которые требуют
значений не-NULL
. See section 2.3.3 Типичные опции configure
.
mysql_insert_id
можно найти величину, использованную
для столбца AUTO_INCREMENT
. See section 8.4.3.31 mysql_insert_id()
.
Если задается команда INSERT ... SELECT
или INSERT ... VALUES
со списками
из нескольких значений, то для получения информации о данном запросе можно
использовать функцию C API mysql_info()
. Формат этой информационной строки
приведен ниже:
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
показывает число строк, которые не могли быть внесены,
поскольку они дублировали бы значения некоторых существующих уникальных
индексов. Указатель Warnings
показывает число попыток внести величину в
столбец, который по какой-либо причине оказался проблематичным.
Предупреждения возникают при выполнении любого из следующих условий:
NULL
в столбец, который был объявлен, как NOT NULL
. Данный
столбец устанавливается в значение, заданное по умолчанию.
'10.34 a'
. Конечные
данные удаляются и вносится только оставшаяся числовая часть. Если
величина вовсе не имеет смысла как число, то столбец устанавливается в
0
.
CHAR
, VARCHAR
, TEXT
или BLOB
строки,
превосходящей максимальную длину столбца. Данная величина усекается до
максимальной длины столбца.
User Comments
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'.
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).
*****************
* 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.
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.
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 ;) )
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')
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.
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.
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?
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.
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.