| |
SELECT
,
INSERT
, UPDATE
, DELETE
SELECT
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [HIGH_PRIORITY] [DISTINCT|DISTINCTROW|ALL] select_expression,... [INTO {OUTFILE|DUMPFILE} 'file_name' export_options] [FROM table_references [WHERE where_definition] [GROUP BY {unsigned_integer|col_name|formula} [ASC|DESC], ...] [HAVING where_definition] [ORDER BY {unsigned_integer|col_name|formula} [ASC|DESC] ,...] [LIMIT [offset,] rows] [PROCEDURE procedure_name] [FOR UPDATE|LOCK IN SHARE MODE]]
SELECT
используется, чтобы отыскать строки, выбранные из
одной или большего количества таблиц. select_expression
указывает столбцы, которые Вы хотите получить. SELECT
может
также использоваться, чтобы получить строки, вычисленные независимо от
любой таблицы. Например:
mysql> SELECT 1 + 1; -> 2
Все используемые ключевые слова должны быть даны точно в порядке,
показанном выше. Например, предложение HAVING
должно прийти
после любого предложения GROUP BY
и перед любым предложением
ORDER BY
.
SELECT
может применять псевдоним, используя AS
.
Псевдоним используется при задании в выражении имени столбца и может быть
указан с предложениями ORDER BY
или HAVING
. Пример:
mysql> select concat(last_name,', ',first_name) AS full_name from mytable ORDER BY full_name;
FROM table_references
указывает таблицы, из
которых надо отыскать строки. Если Вы называете больше, чем одну таблицу, Вы
выполняете объединение. Для получения информации относительно синтаксиса
объединения обратитесь к разделу "8.1.1 Синтаксис
JOIN
".
col_name
,
tbl_name.col_name
или db_name.tbl_name.col_name
. Вы
не должны определять префикс tbl_name
или
db_name.tbl_name
для ссылки столбца в инструкции
SELECT
, если ссылка однозначна. Подробности в разделе
"3.2 Имена баз данных, таблиц, индексов,
столбцов и псевдонимов", там есть примеры неоднозначности, которые
требуют более явных форм ссылки.
tbl_name [AS] alias_name
:
mysql> select t1.name, t2.salary from employee AS t1, info AS t2 where t1.name = t2.name; mysql> select t1.name, t2.salary from employee t1, info t2 where t1.name = t2.name;
ORDER BY
и GROUP BY
использующими имена столбца,
псевдонимы столбца или позицию столбца. Позиции столбца начинаются с 1:
mysql> select college, region, seed from tournament ORDER BY region, seed; mysql> select college, region AS r, seed AS s from tournament ORDER BY r, s; mysql> select college, region, seed from tournament ORDER BY 2, 3;Чтобы сортировать в обратном порядке, добавьте к имени столбца в предложении
ORDER BY
, которым Вы сортируете, ключевое слово
DESC
. Значение по умолчанию: порядок возрастания, это может быть
определено, явно используя ключевое слово ASC
.
WHERE
использовать любую из функций
MySQL. Подробности в разделе "6 Функции для
использования в предложениях SELECT
и WHERE
".
HAVING
может обратиться к любому столбцу или
псевдониму, именованному в select_expression
. Это применяется в
последнюю очередь прежде, чем элементы будут посланы пользователю, без
оптимизации. Не используйте HAVING
для элементов, которые должны
быть в предложении WHERE
. Например, не пишите это:
mysql> select col_name from tbl_name HAVING col_name > 0;Пишите это взамен:
mysql> select col_name from tbl_name WHERE col_name > 0;В MySQL Version 3.22.5 или позже Вы можете также писать запросы подобно этому:
mysql> select user,max(salary) from users group by user HAVING max(salary)>10;В старых версиях MySQL Вы можете писать взамен это:
mysql> select user,max(salary) AS sum from users group by user HAVING sum>10;
SQL_SMALL_RESULT
, SQL_BIG_RESULT
,
SQL_BUFFER_RESULT
, STRAIGHT_JOIN
и
HIGH_PRIORITY
представляют собой MySQL-расширения ANSI SQL92.
HIGH_PRIORITY
даст SELECT
более высокий
приоритет, чем инструкциям, которые модифицируют таблицу. Вы должны
использовать это только для запросов, которые являются очень быстрыми и
должны быть выполнены сразу. Запрос SELECT HIGH_PRIORITY
выполнится, если таблица блокирована для чтения, даже если имеется инструкция
модификации, которая ждет таблицу.
SQL_BIG_RESULT
может использоваться с GROUP BY
или DISTINCT
, чтобы сообщить оптимизатору, что набор результатов
будет иметь много строк. В этом случае MySQL использует дисковые временные
таблицы если необходимо. MySQL будет также, в этом случае, предпочитать
сортировку временной таблицы с ключом на элементах GROUP BY
.
GROUP BY
, строки
вывода будут сортироваться согласно GROUP BY
, как будто Вы имели
ORDER BY
над всеми полями в GROUP BY
. MySQL
расширил GROUP BY
так, что Вы можете также определять
ASC
и DESC
для GROUP BY
:
SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
GROUP BY
так, чтобы позволить
Вам выбирать поля, которые не упомянуты в предложении GROUP BY
.
Если Вы не получаете те результаты, которых Вы ожидаете от Вашего запроса,
пожалуйста, прочитайте описание на GROUP BY
. Подробности в
разделе "14 Функции для
использования с предложением GROUP BY
".
SQL_BUFFER_RESULT
принудительно поместит результат во
временную таблицу. Это поможет MySQL освободить блокированную таблицу
пораньше и пригодится в случаях, где требуется длительное время, чтобы
послать набор результатов пользователю.
SQL_SMALL_RESULT
опция, специфичная для MySQL, может
использоваться с GROUP BY
или DISTINCT
, чтобы
сообщить оптимизатору, что набор результатов будет маленький. В этом случае
MySQL использует быстрые временные таблицы, чтобы сохранить возникающую в
результате таблицу вместо того, чтобы использовать сортировку.
STRAIGHT_JOIN
заставляет оптимизатор соединять таблицы в том
порядке, в котором они перечислены в предложении FROM
. Вы можете
использовать это, чтобы ускорить запрос, если оптимизатор соединяет таблицы в
неоптимальном порядке.
LIMIT
может использоваться, чтобы ограничить
число строк, возвращенных инструкцией SELECT
. LIMIT
берет один или два числовых параметра. Если два параметра заданы, первый
определяет смещение первой строки, которая будет возвращена, второй
определяет максимальное число строк. Смещение начальной строки 0 (не 1!):
mysql> select * from table LIMIT 5,10; # Вернуть строки 6-15Если один параметр задан, он указывает максимальное число строк:
mysql> select * from table LIMIT 5; # Вернуть первые 5 строкДругими словами,
LIMIT n
эквивалентно LIMIT 0,n
.
SELECT ... INTO OUTFILE
'file_name'
пишет выбранные строки в файл. Он будет создан на сервере
и не может уже существовать (среди других полезных свойств, это защищает от
разрушения некоторыми шутниками файлов типа /etc/passwd). Вы должны
иметь привилегию file на сервере, чтобы использовать эту
форму вызова SELECT
.
SELECT ... INTO OUTFILE
главным образом предназначен для того,
чтобы позволить Вам очень быстро сделать дамп таблицы на сервере. Если Вы
хотите создавать возникающий в результате файл на некотором другом
компьютере, Вы не можете использовать SELECT ... INTO OUTFILE
. В
этом случае Вы должны взамен использовать какую-нибудь программу-клиента,
подобную mysqldump --tab
или mysql -e "SELECT ..." >
outfile
, чтобы генерировать файл.
SELECT ... INTO OUTFILE
дополнение синтаксиса LOAD DATA
INFILE
. Синтаксис для части инструкции export_options
состоит из тех же самых предложений FIELDS
и LINES
,
которые используются с инструкцией LOAD DATA INFILE
. Подробности
в разделе "8.9 Синтаксис LOAD DATA
INFILE
". В возникающем в результате текстовом файле только
следующие символы закодированы через символ ESCAPED BY
:
ESCAPED BY
FIELDS TERMINATED BY
LINES TERMINATED BY
ASCII 0
будет преобразован в ESCAPED
BY
, сопровождаемый 0 (ASCII 48
).
Причина для вышеупомянутого в том, что Вы ДОЛЖНЫ выйти из любых символов
FIELDS TERMINATED BY
, ESCAPED BY
или LINES
TERMINATED BY
, чтобы надежно читать файл обратно. ASCII 0
экранирован, чтобы сделать это проще. Поскольку возникающий в результате файл
не должен соответствовать SQL-синтаксису, ничто иное не должно
экранироваться. Пример получения файла в формате, используемом многими
довольно старыми программами:
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM test_table;
INTO DUMPFILE
вместо INTO OUTFILE
, MySQL будет только писать одну строку в
файл, без любого выравнивания или экранировки управляющих символов. Это
полезно, если Вы хотите сохранять blob в файле.
INTO OUTFILE
и
INTO DUMPFILE
будет читаемым для всех пользователей! Причина в
том, что сервер MySQL не может создавать файл, который принадлежит кому-либо
другому, а не пользователю, который запустил сервер. Вы не должны никогда
выполнять mysqld
как root!), файл должен быть доступен на чтение
всем желающим, чтобы Вы могли получать из него строки.
FOR UPDATE
с драйвером таблиц,
поддерживающем блокировки страницы/столбца, нужные столбцы будут
заблокированы для записи.JOIN
MySQL поддерживает следующие синтаксисы JOIN
для применения в
операторе выбора SELECT
:
table_reference, table_reference table_reference [CROSS] JOIN table_reference table_reference INNER JOIN table_reference join_condition table_reference STRAIGHT_JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference join_condition table_reference LEFT [OUTER] JOIN table_reference table_reference NATURAL [LEFT [OUTER]] JOIN table_reference { oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr } table_reference RIGHT [OUTER] JOIN table_reference join_condition table_reference RIGHT [OUTER] JOIN table_reference table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
Здесь table_reference
определен как:
table_name [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)]
а join_condition
как:
ON conditional_expr | USING (column_list)
Вы никогда не должны иметь никаких условий в части ON
,
которые используются, чтобы ограничить то, какие строки Вы получите в наборе
результатов. Если Вы хотите оговорить то, которые строки должны быть в
результате, Вы должны делать это в предложении WHERE
.
Обратите внимание, что в версиях до Version 3.23.17 INNER
JOIN
не обрабатывал join_condition
!
Последний синтаксис LEFT
OUTER JOIN
, показанный выше, существует только для совместимости с ODBC:
tbl_name AS alias_name
или tbl_name alias_name
:
mysql> select t1.name, t2.salary from employee AS t1, info AS t2 where t1.name = t2.name;
ON
представляет собой любое условное
выражение формы, которое может использоваться в предложении
WHERE
.
ON
или USING
в LEFT JOIN
, используется
строка со всем набором столбцов, выставленным в NULL
. Вы можете
использовать этот факт, чтобы найти записи в таблице, которые не имеют
никакого дубликата в другой таблице:
mysql> select table1.* from table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id is NULL;Этот пример находит все строки в
table1
со значением
идентификатора id
, которое не представлено в table2
(то есть, все строки в table1
без соответствующей строки в
table2
). Это подразумевает, что table2.id
объявлен
как NOT NULL
.
USING
(column_list)
объявляет список столбцов,
которые должны существовать в обеих таблицах. Предложение типа
USING
:
A LEFT JOIN B USING (C1,C2,C3,...)Определено, чтобы быть семантически идентичным выражению
ON
:
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
NATURAL [LEFT] JOIN
двух таблиц определено семантически
эквивалентно INNER JOIN
или LEFT JOIN
с
предложением USING
с именами всех столбцов, которые существуют в
обеих таблицах.
RIGHT JOIN
работает аналогично LEFT JOIN
. Чтобы
сохранить код переносимым между базами данных, рекомендует использовать
LEFT JOIN
вместо RIGHT JOIN
.
STRAIGHT_JOIN
идентичен JOIN
, за исключением
того, что левая таблица всегда читается перед правой таблицей. Это может
использоваться для тех немногих случаев, когда оптимизатор объединения
помещает таблицы в неправильном порядке.
EXPLAIN
показывает, что MySQL использует
неправильный индекс. Определяя USE INDEX (key_list)
, Вы можете
сообщать, чтобы MySQL использовал только один из определенных индексов, чтобы
найти строки в таблице. Альтернативный синтаксис IGNORE INDEX
(key_list)
может использоваться, чтобы сообщить, чтобы MySQL не
использовал некоторый специфический индекс.Вот некоторые примеры:
mysql> select * from table1,table2 where table1.id=table2.id; mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> select * from table1 LEFT JOIN table2 USING (id); mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id; mysql> select * from table1 USE INDEX (key1,key2) WHERE key1=1 and key2=2 AND key3=3; mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND key3=3;
UNION
SELECT .... UNION [ALL] SELECT .... [UNION SELECT ...]
UNION
реализован только в версии MySQL 4.0.0 и выше.
UNION
используется, чтобы объединить результаты из многих
инструкций SELECT
в один набор результатов.
Команды SELECT
представляют собой нормальные команды выбора,
но со следующими ограничениями:
SELECT
может иметь INTO
OUTFILE
.
SELECT
может иметь ORDER
BY
.Если Вы не используете ключевое слово ALL
для
UNION
, все возвращенные строки будут уникальны, подобно тому,
как если бы Вы сделали DISTINCT
для общего набора результатов.
Если Вы определяете ALL
, то Вы получите все строки соответствий
из всех используемых инструкций SELECT
.
INSERT
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES (expression,...),(...),... INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ... INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name SET col_name=expression, col_name=expression, ...
INSERT
вставляет новые строки в существующую таблицу. Форма
INSERT ... VALUES
вставляет строки, основываясь на явно
определенных значениях. INSERT ... SELECT
вставляет строки,
выбранные из другой таблицы или таблиц. Форма INSERT ... VALUES
с несколькими списками значений поддержана в MySQL Version 3.22.5 или позже.
Синтаксис col_name=expression
введен, начиная с MySQL Version
3.22.10 или выше.
tbl_name
таблица, в которую строки должны быть вставлены.
Список имен столбцов или предложение SET
указывает, для которых
столбцов инструкция определяет значения:
INSERT ...
VALUES
или INSERT ... SELECT
, значения для всех столбцов
нужно обеспечить в списке VALUES()
или через
SELECT
. Если Вы не знаете порядка столбцов в таблице,
используйте DESCRIBE tbl_name
, чтобы выяснить.
CREATE TABLE
".
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
, которая позволяет пользователю продолжать работу сразу же.
Подробности в разделе "8.4 Синтаксис
INSERT DELAYED
". Обратите внимание, что
LOW_PRIORITY
обычно не должен использоваться с таблицами
MyISAM
, поскольку это отключает параллельные вставки.
IGNORE
в
INSERT
со многими строками значений, любые строки, которые
дублируют существующий ключ PRIMARY
или UNIQUE
в
таблице, игнорируются и не будут вставлены. Если Вы не определяете
IGNORE
, вставка будет прервана, если имеется любая строка,
которая дублирует существующее значение ключа. Вы можете определять в функции
C API mysql_info()
, сколько строк были вставлены в таблицу.
DONT_USE_DEFAULT_FIELDS
, инструкции INSERT
генерируют ошибку, если Вы явно не определяете значения для всех столбцов,
которые требуют значения, отличного от NULL
.Если Вы используете 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
. Значение усечено к максимальной длине столбца.
INSERT ... SELECT
INSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ...
Командой INSERT ... SELECT
Вы можете быстро вставлять много
строк в таблицу из одной или нескольких таблиц.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
Следующие условия работают для команды INSERT ... SELECT
:
INSERT
не может появляться в
предложении FROM
части SELECT
запроса потому, что
в ANSI SQL запрещено выполнять SELECT
над той же самой таблицей,
в которую Вы вставляете. Проблема состоит в том, что SELECT
,
возможно, нашел бы записи, которые были вставлены ранее в течение той же
самой операции. При использовании предложений sub-select, ситуация могла бы
очень легко запутаться!
AUTO_INCREMENT
работают как обычной.
mysql_info()
, чтобы
получить информацию относительно запроса. Подробности в разделе
"8.3 Синтаксис INSERT
".
INSERT ... SELECT
.Вы можете, конечно, также использовать REPLACE
вместо
INSERT
, чтобы перезаписать старые строки.
INSERT DELAYED
INSERT DELAYED ...
Опция DELAYED
для инструкции INSERT
специфична
для MySQL и является очень полезной, если Вы имеете клиентуру, которая не
может ждать завершения INSERT
. Это общая проблема, когда Вы
используете MySQL для регистрации и также периодически выполняете инструкции
SELECT
и UPDATE
, которые занимают много времени.
DELAYED
введен в MySQL Version 3.22.15. Это MySQL-расширение для
стандарта ANSI SQL92.
INSERT DELAYED
работает только с таблицами ISAM
и MyISAM
. Обратите внимание, что таблицы MyISAM
поддерживают параллельные SELECT
и INSERT
, если не
имеется никаких свободных блоков в середине файла данных, Вы очень редко
должны использовать INSERT DELAYED
с таблицами типа
MyISAM
.
Когда Вы используете INSERT DELAYED
, клиент получит сообщение
OK сразу, а вот строка будет вставлена, когда таблица не будет использоваться
любым другим потоком.
Другая польза от применения INSERT DELAYED
в том, что вставки
многих клиентов будут связаны вместе и записаны в одном блоке. Это намного
быстрее, чем выполнение многих отдельных вставок.
Обратите внимание, что в настоящее время поставленные в очередь строки
сохранены только в памяти, пока они не вставлены в таблицу. Это означает,
что, если Вы уничтожаете mysqld
крутыми мерами
(kill -9
), или если mysqld
рухнет неожиданно, любые
поставленные в очередь строки, которые не были записаны на диск, потеряются!
Следующее описывает подробно, что случается, когда Вы используете опцию
DELAYED
вместе с командами INSERT
или
REPLACE
. В этом описании "поток" представляет собой поток,
который получил команду INSERT DELAYED
, и "драйвер" обозначает
поток, который обрабатывает все инструкции INSERT DELAYED
для специфической таблицы.
DELAYED
для таблицы,
будет создан драйвер: чтобы обработать все инструкции DELAYED
для этой таблицы, если никакого такого драйвера еще не существует.
DELAYED
. Если нет, он сообщает, чтобы драйвер это сделал.
Блокировка DELAYED
может быть получена, даже если другие потоки
имеют блокировку READ
или WRITE
на таблице. Однако,
драйвер будет ждать ALTER TABLE
или FLUSH TABLES
,
чтобы гарантировать, что текущая структура таблицы современна.
INSERT
, но вместо того, чтобы
записать строку в таблицу, он помещает копию конечной строки в очередь,
которая управляется драйвером. Любые ошибки синтаксиса будут отмечены потоком
и сообщены программе пользователя.
AUTO_INCREMENT
для возникающей в результате строки. Он не может
получить эти данные с сервера, поскольку возвраты INSERT
перед
операцией вставки был завершены.
delayed_insert_limit
строк написаны,
драйвер проверяет, являются или нет любые инструкции SELECT
ждущими своей очереди. Если это так, драйвер позволяет им выполниться перед
продолжением своей работы.
INSERT DELAYED
не появилась в течение последних
delayed_insert_timeout
секунд, драйвер завершается.
delayed_queue_size
строк, ждущих обработки,
уже в специфической очереди драйверов, поток, запрашивающий INSERT
DELAYED
ждет до появления участка памяти в очереди. Это выполнено,
чтобы гарантировать, что сервер mysqld
не использует всю память
для отсроченной очереди.
delayed_insert
в столбце Command
. Это будет
уничтожаться, если Вы выполняете команду FLUSH TABLES
или
уничтожаете поток с помощью KILL thread_id
. Однако, драйвер
сначала сохранит все поставленные в очередь строки в таблицу перед выходом. В
это время система не будет принимать никакие новые команды
INSERT
от других потоков. Если Вы выполняете команду
INSERT DELAYED
после того, как это было выполнено, новый поток
драйвера будет создан.
INSERT
DELAYED
имеют более высокий приоритет, чем нормальные команды
INSERT
, если уже имеется драйвер INSERT DELAYED
!
Другие команды модификации должны будут ждать до опустошения очереди
INSERT DELAYED
, уничтожения драйвера (через KILL
thread_id
) или выполнения FLUSH TABLES
.
INSERT DELAYED
:
Переменная | Значение |
Delayed_insert_threads | Число обработчиков потоков |
Delayed_writes | Число строк, вставленных с
помощью INSERT DELAYED |
Not_flushed_delayed_rows | Число строк, ждущих записи |
SHOW
STATUS
или выполняя команду mysqladmin extended-status
.
Обратите внимание, что INSERT DELAYED
медленнее, чем
нормальная INSERT, если таблица сейчас не используется. Имеется также
дополнительная нагрузка для сервера, чтобы обработать отдельный поток для
каждой таблицы, на которой Вы используете INSERT DELAYED
. Это
означает, что Вы должны использовать INSERT DELAYED
только
тогда, когда Вы, действительно, уверены, что нуждаетесь в этом!
UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1, [col_name2=expr2, ...] [WHERE where_definition] [LIMIT #]
UPDATE
модифицирует столбцы в существующих строках таблиц с
новыми значениями. Предложение SET
указывает, какие столбцы
изменять, и значения, которые им должны быть заданы. Предложение
WHERE
, если задано, определяет, какие строки должны
модифицироваться. Иначе модифицируются все строки. Если определено
предложение ORDER BY
, строки будут модифицироваться в том
порядке, который определен.
Если Вы определяете ключевое слово LOW_PRIORITY
, выполнение
UPDATE
будет отсрочено до наступления момента, когда никакие
клиенты не читают из таблицы.
Если Вы определяете ключевое слово IGNORE
, инструкция
модификации не будет прерываться, даже если мы получаем ошибки дублирования
ключа в течение модификации. Строки, которые могли бы вызвать конфликты, не
будут модифицироваться вообще.
Если Вы обращаетесь к столбцу из tbl_name
в выражении,
UPDATE
использует текущее значение столбца. Например, следующая
инструкция устанавливает столбец age
к следующему за его текущим
значением:
mysql> UPDATE persondata SET age=age+1;
Назначения UPDATE
оценены слева направо. Например, следующая
инструкция удваивает столбец age
, затем увеличивает его на 1:
mysql> UPDATE persondata SET age=age*2, age=age+1;
Если Вы устанавливаете столбец к значению, которое он в настоящее время имеет, MySQL не обращает внимания на это и не модифицирует столбец!
UPDATE
возвращает число строк, которые
были фактически изменены. В MySQL Version 3.22 или позже функция C API
mysql_info()
возвращает число строк, которые были согласованы и
модифицировались, и число предупреждений, которые произошли в течение
UPDATE
.
В MySQL Version 3.23 Вы можете использовать LIMIT #
, чтобы
гарантировать, что только заданное число строк будет изменено.
DELETE
DELETE [LOW_PRIORITY | QUICK] FROM table_name [WHERE where_definition] [ORDER BY ...] [LIMIT rows] DELETE [LOW_PRIORITY | QUICK] table_name[.*] [table_name[.*] ...] FROM table-references [WHERE where_definition]
DELETE
удаляет строки, которые удовлетворяют условию,
заданному в where_definition
из таблицы table_name
и возвращает число удаленных записей.
Если Вы выдаете DELETE
без предложения WHERE
,
все строки будут удалены. Если Вы делаете это в режиме
AUTOCOMMIT
, это сработает аналогично TRUNCATE
.
Подробности в разделе "8.7 Синтаксис
TRUNCATE
". В MySQL 3.23 DELETE
без предложения
WHERE
возвратит ноль как число обработанных записей.
Если Вы действительно хотите знать, сколько записей удалены, когда Вы
удаляете все строки из таблицы, Вы можете использовать инструкцию
DELETE
этой формы:
mysql> DELETE FROM table_name WHERE 1>0;
Обратите внимание, что это НАМНОГО медленнее, чем DELETE FROM
table_name
без предложения WHERE
потому, что эта команда
удаляет строки по одной.
Если Вы определяете ключевое слово LOW_PRIORITY
, выполнение
DELETE
будет отсрочено до наступления момента, когда никакие
клиенты не читают из таблицы.
Если Вы определяете слово QUICK
, то драйвер таблицы не будет
объединять индексные листья в течение процесса удаления, что может ускорять
некоторые виды удаления.
В MyISAM-таблицах удаленные записи поддерживаются в связанном списке, и
старые позиции записей повторно используются вызовом INSERT
.
Чтобы освободить неиспользуемое место и уменьшить размеры файла, используйте
команду OPTIMIZE TABLE
или утилиту myisamchk
, чтобы
реорганизовать таблицы. OPTIMIZE TABLE
проще, но
myisamchk
быстрее. Подробности в разделе
"4.6 Синтаксис OPTIMIZE
TABLE
".
Вы можете удалять строки из многих таблиц в то же самое время, а также иметь дополнительные таблицы, которые используются для поиска.
Символ .*
после имени таблицы появился для совместимости с
Access
:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
В вышеупомянутом случае мы удаляем строки соответствий только из таблиц
t1
и t2
.
ORDER BY
и использование нескольких таблиц в DELETE
реализовано, начиная с MySQL 4.0.
Если предложение ORDER BY
используется, строки будут удалены
в заданном порядке. Это удобно в сочетании с LIMIT
. Например:
DELETE FROM somelog WHERE user='jcole' ORDER BY timestamp LIMIT 1
Это удалит самую старую запись (по timestamp
), где строка
соответствует предложению WHERE
.
MySQL-специфичная опция LIMIT rows
функции
DELETE
сообщает серверу максимальное число строк, которые будут
удалены прежде, чем управление будет возвращено пользователю. Это может
использоваться, чтобы гарантировать, что специфическая команда
DELETE
не займет слишком много времени. Вы можете просто
повторять команду DELETE
, пока число обрабатываемых строк не
меньше, чем значение LIMIT
.
TRUNCATE
TRUNCATE TABLE table_name
В версии 3.23 TRUNCATE TABLE
отображен на вызов COMMIT;
DELETE FROM table_name
. Подробности в разделе
"8.6 Синтаксис DELETE
".
Разница между TRUNCATE TABLE
и DELETE FROM ..
:
TRUNCATE
представляет собой Oracle-расширение языка SQL.
REPLACE
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES (expression,...),(...),... REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT ... REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name=expression, col_name=expression,...
REPLACE
работает в точности подобно INSERT
, за
исключением того, что, если старая запись в таблице имеет то же самое
значение, что и новая запись на уникальном индексе, старая запись будет
удалена прежде, чем новая запись вставлена в таблицу. Подробности в разделе
"8.3 Синтаксис INSERT
".
Другими словами, Вы не можете обращаться к значениям старой строки из
инструкции REPLACE
. В некоторых старых версиях MySQL могли, но
это было ошибкой, которая исправлена.
При использовании вызова REPLACE
mysql_affected_rows()
возвратит 2, если новая строка заменила
старую. Это потому, что в этом случае одна строка была вставлена, а затем
дубликат был удален.
LOAD DATA INFILE
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE tbl_name [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES TERMINATED BY '\n'] [IGNORE number LINES] [(col_name,...)]
Команда LOAD DATA INFILE
читает строки из текстового файла в
таблицу. Если ключевое слово LOCAL
определено, файл читается с
компьютера пользователя. Если LOCAL
не определено, файл должен
быть размещен на сервере. LOCAL
доступен в MySQL Version 3.22.6
или более поздней.
По соображениям безопасности, при чтении текстовых файлов, размещенных на
сервере, файлы должны находиться в каталоге баз данных или быть читаемыми
всеми. Также, чтобы использовать LOAD DATA INFILE
на файлах
сервера, Вы должны иметь привилегию file. Подробности в
разделе "10.6 Привилегии,
предоставляемые MySQL".
Если Вы определяете ключевое слово LOW_PRIORITY
, выполнение
LOAD DATA
будет отложено до тех пор, пока другая клиентура не
прекратит читать из таблицы.
Если Вы определяете ключевое слово CONCURRENT
с таблицей типа
MyISAM
, то другие потоки могут получать данные из таблицы в то
время, как выполняется LOAD DATA
. Использование этой опции
будет, конечно, воздействовать на эффективность LOAD DATA
, даже
если никакой другой поток не использует таблицу в то же самое время.
Использование LOCAL
будет немного медленнее, чем разрешение
серверу обращаться к файлам непосредственно потому, что содержание файла
должно пропутешествовать с компьютера пользователя на сервер. С другой
стороны, Вы не нуждаетесь в привилегии file, чтобы загрузить
свои локальные файлы.
Если Вы используете MySQL ниже 3.23.24, Вы не можете читать из FIFO с
помощью LOAD DATA INFILE
. Если Вы должны читать из FIFO
(например, вывод из gunzip), используйте вместо этого команду LOAD
DATA LOCAL INFILE
.
Вы можете также загружать файлы данных, используя
полезность mysqlimport
. Она функционирует, посылая команду
LOAD DATA INFILE
на сервер. Опция --local
заставляет mysqlimport
читать файлы данных с компьютера
пользователя. Вы можете определять опцию --compress
, чтобы
получить лучшую эффективность при работе с медленными сетями, если
пользователь и сервер поддерживают сжатый протокол.
При размещении файлов на компьютере сервера, он использует правила:
Обратите внимание, что эти правила означают, что файл, заданный как
./myfile.txt, читается из каталога данных сервера в то время, как
файл myfile.txt читается из каталога текущей базы данных. Например,
следующая инструкция LOAD DATA
читает файл data.txt из
каталога базы данных для db1
потому, что db1
текущая база данных, даже при том, что инструкция явно загружает файл в
таблицу в базе данных db2
:
mysql> USE db1; mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;
Ключевые слова REPLACE
и IGNORE
контролируют
обработку записей, которые дублируют существующие записи на уникальных
значениях ключа. Если Вы определяете REPLACE
, новые строки
заменяют существующие, которые имеют то же самое уникальное значение ключа.
Если Вы определяете IGNORE
, строки, которые дублируют
существующие на уникальном значении ключа, будут пропущены. Если Вы не
определяете никакую опцию, ошибка происходит, когда будет найдено двойное
значение ключа, и остальная часть текстового файла игнорируется.
Если Вы загружаете данные из локального файла, используя ключевое слово
LOCAL
, сервер не имеет никакого способа остановить передачу
файла в середине операции, так что значение по умолчанию такое же, как если
определена опция IGNORE
.
Если Вы используете LOAD DATA INFILE
на пустой таблице
MyISAM
, все неуникальные индексы будут созданы в отдельном
пакете (подобно REPAIR
). Это обычно делает LOAD DATA
INFILE
намного быстрее, когда Вы имеете много индексов.
LOAD DATA INFILE
представляет собой дополнение к SELECT
... INTO OUTFILE
. Подробности в разделе
"8.1 Синтаксис SELECT
". Чтобы
писать данные из базы данных в файл, используйте SELECT ... INTO
OUTFILE
. Чтобы читать файл обратно в базу данных, используйте
LOAD DATA INFILE
. Синтаксис предложений FIELDS
и
LINES
тот же самый для обеих команд. Оба предложения
факультативные, но FIELDS
должно предшествовать
LINES
, если оба определены.
Если Вы определяете предложение FIELDS
, каждое из
подпредложений (TERMINATED BY
, [OPTIONALLY] ENCLOSED
BY
и ESCAPED BY
) также факультативны за исключением того,
что Вы должны определить по крайней мере одно из них.
Если Вы не определяете предложение FIELDS
, значения по
умолчанию были бы такие же, как если бы Вы написали это:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Если Вы не определяете предложение LINES
, значения по
умолчанию были бы такие же, как если бы Вы написали это:
LINES TERMINATED BY '\n'
Другими словами, значения по умолчанию заставляют LOAD DATA
INFILE
действовать следующим образом при чтении ввода:
SELECT ... INTO OUTFILE
по умолчанию должен действовать
следующим образом при записи вывода:
Обратите внимание, что, чтобы писать FIELDS ESCAPED BY '\\'
,
Вы должны определить две наклонных черты влево для любого значения, которое
нужно читать как одиночную наклонную черту влево.
Опция IGNORE number LINES
может использоваться, чтобы
игнорировать заголовок столбца в начале файла:
mysql> LOAD DATA INFILE "/tmp/file_name" into table test IGNORE 1 LINES;
Когда Вы используете SELECT ... INTO OUTFILE
в тандеме с
LOAD DATA INFILE
, чтобы записать данные из базы данных в файл, а
затем читаете файл обратно в базу данных позже, параметры обработки поля и
строк для обеих команд должны соответствовать. Иначе LOAD DATA
INFILE
не будут интерпретировать содержание файла правильно.
Предположите, что Вы используете SELECT ... INTO OUTFILE
, чтобы
записать файл с полями, разграниченными запятыми:
mysql> SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM ...;
Чтобы прочитать разграниченный запятыми файл обратно в базу данных, правильная инструкция была бы такой:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';
Если взамен Вы пробовали читать файл инструкцией, показанной ниже, это не
будет работать потому, что это инструктирует LOAD DATA INFILE
искать позиции табуляции между полями:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';
Вероятный результат: каждая входная строка интерпретируется как одиночное поле без разделения на поля.
LOAD DATA INFILE
может использоваться, чтобы читать файлы,
полученные из внешних источников. Например, файл в формате dBASE будет иметь
поля, разделяемые запятыми и заключенные в двойные кавычки. Если строки в
файле завершены newlines, команда, показанная ниже, иллюстрирует параметры
обработки, которые Вы использовали бы, чтобы загрузить файл:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
Любое из поля или параметров обработки может определять пустую строку
(''
). Если она не пустая, значения FIELDS [OPTIONALLY]
ENCLOSED BY
и FIELDS ESCAPED BY
должны быть одиночным
символом. Значения FIELDS TERMINATED BY
и LINES TERMINATED
BY
могут быть больше, чем одним символом. Например, чтобы писать
строки, которые завершены парами carriage return-linefeed, или читать файл,
содержащий такие строки, определите LINES TERMINATED BY '\r\n'
.
Например, чтобы читать файл записей, которые отделяются строкой
%%
, в таблицу SQL, Вы можете сделать:
create table jokes (a int not null auto_increment primary key, joke text not null); load data infile "/tmp/jokes.txt" into table jokes fields terminated by "" lines terminated by "\n%%\n" (joke);
FIELDS [OPTIONALLY] ENCLOSED BY
управляет цитированием полей.
Для вывода (SELECT ... INTO OUTFILE
), если Вы опускаете слово
OPTIONALLY
, все поля включены символом ENCLOSED BY
.
Пример такого вывода (использование запятой как разделителя поля) ниже:
"1","a string","100.20" "2","a string containing a , comma","102.20" "3","a string containing a \" quote","102.20" "4","a string containing a \", quote and comma","102.20"
Если Вы определяете OPTIONALLY
, символ
ENCLOSED BY
используется только для того, чтобы включить поля
типов CHAR
и VARCHAR
:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a \" quote",102.20 4,"a string containing a \", quote and comma",102.20
Обратите внимание, что местонахождение символа ENCLOSED BY
внутри значения поля экранируется приписыванием символа
ESCAPED BY
. Также обратите внимание, что, если Вы определяете
пустое значение ESCAPED BY
, возможно генерировать вывод, который
не может читаться правильно средствами LOAD DATA INFILE
.
Например, вывод, показанный выше, появился бы как показано ниже, если бы
символ ESC был пустым. Заметьте, что второе поле в четвертой строке содержит
запятую после кавычки, которая ошибочно появляется и завершает поле:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a " quote",102.20 4,"a string containing a ", quote and comma",102.20
Для ввода символ ENCLOSED BY
, если он вообще задан, будет
удален с концов значений поля. Это истинно, определен или нет
OPTIONALLY
. OPTIONALLY
не имеет никакого эффекта на
входной интерпретации. Местонахождения символа ENCLOSED BY
,
которому предшествует символ ESCAPED BY
, интерпретируются как
часть текущего значения поля. Кроме того, дублированные символы
ENCLOSED BY
, встречающиеся внутри полей, интерпретируются как
одиночные символы ENCLOSED BY
, если поле непосредственно
начинается этим символом. Например, если определено
ENCLOSED BY '"'
, кавычки будут обработаны как показано ниже:
"The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY
контролирует, как писать или читать
специальные символы. Если символ FIELDS ESCAPED BY
не пуст, он
использует для префикса следующие символы на выводе:
FIELDS ESCAPED BY
.
FIELDS [OPTIONALLY] ENCLOSED BY
.
FIELDS TERMINATED BY
и
LINES TERMINATED BY
.
0
(что фактически написано после символа ASCII
0
, не нулевой байт).Если символ FIELDS ESCAPED BY
пуст, никакие символы не
экранируются вовсе. Не стоит определять пустой символ ESC, особенно, если
значения полей в Ваших данных содержат любой из символов в списке выше.
Для ввода, если символ FIELDS ESCAPED BY
не пуст,
местонахождения этого символа будут удалены, и следующий символ принимается
буквально как часть значения поля. Исключительные ситуации: 0
или N (например, \0
или \N
, если
символ ESC задан как \). Эти последовательности интерпретируются
как 0
и NULL
соответственно. Ниже изложены правила
для обработки NULL
.
За подробностями относительно синтаксиса экранировки с символом \ отсылаю Вас к разделу "3.1 Литералы: как писать строки и числа".
В некоторых случаях параметры обработки полей и строк взаимодействуют:
LINES TERMINATED BY
пустая строка, а FIELDS
TERMINATED BY
не пустая, строки также будут завершены
FIELDS TERMINATED BY
.
FIELDS TERMINATED BY
и
FIELDS ENCLOSED BY
пусты (''
), используется
фиксированный формат. С этим форматом никакие разделители не используются
между полями. Вместо этого, значения столбцов пишутся и читаются, используя
"экранную" ширину. Например, если столбец объявлен как INT(7)
,
значения для столбца будут написаны, используя 7-символьные поля. На вводе
значения для столбца будут получены, читая 7 символов. Формат фиксированной
строки также воздействует на обработку значений NULL
(см. ниже).
Обратите внимание, что этот формат не будет работать, если Вы используете
многобайтный набор символов.Обработка значений NULL
изменяется, в зависимости от
параметров FIELDS
и LINES
, которые Вы используете:
FIELDS
и
LINES
NULL
будет написан как \N
для
вывода, а \N
читается как NULL
для ввода
(подразумевается, что символ ESCAPED BY
определен как
\).
FIELDS ENCLOSED BY
не пуст, поле, содержащее
литеральное слово NULL
, читается как значение NULL
(это отличается от слова NULL
, заключенного внутри символов
FIELDS ENCLOSED BY
, которое читается как строка
'NULL'
).
FIELDS ESCAPED BY
пустое, NULL
будет
написан как слово NULL
.
FIELDS TERMINATED BY
и FIELDS ENCLOSED BY
оба пусты), NULL
будет записан
как пустая строка. Обратите внимание, что это делает неразличимыми значения
NULL
и пустые строки в таблице, когда они записаны в файл
потому, что и то и другое пишется как как пустые строки. Если Вы должны при
чтении файла иметь возможность разобраться что есть что, не следует применять
фиксированный формат строки.Некоторые случаи не поддержаны LOAD DATA INFILE
:
FIELDS TERMINATED BY
и
FIELDS ENCLOSED BY
вместе пустые) в сочетании со столбцами
BLOB
или TEXT
.
LOAD DATA INFILE
не будет способна интерпретировать ввод
правильно. Например, следующее предложение FIELDS
проблемное:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
FIELDS ESCAPED BY
пуст, значение поля, которое
содержит FIELDS ENCLOSED BY
или LINES TERMINATED
BY
, сопровождаемое значением FIELDS TERMINATED BY
,
заставит LOAD DATA INFILE
перестать читать поле или строку
слишком рано. Это случается потому, что LOAD DATA INFILE
не
может правильно определять, где заканчивается поле.Следующий пример загружает все столбцы таблицы persondata
:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Никакой список полей не определен, так что LOAD DATA INFILE
ожидает строки, содержащие поле для каждого столбца таблицы. Используются
заданные по умолчанию значения FIELDS
и LINES
.
Если Вы желаете загрузить только некоторые из столбцов таблицы, определите список полей:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);
Вы должны также определить список полей, если порядок полей во входном файл отличается от порядка столбцов в таблице. Иначе MySQL не может выяснить, как совмещать входные поля со столбцами таблицы.
Если строка имеет слишком мало полей, столбцы, для которых никакого
входного поля не присутствует, будут установлены в значения по умолчанию.
Задание этих значений по умолчанию подробно описано в разделе
"7.3 Синтаксис CREATE TABLE
".
Пустое значение поля интерпретируется не так, как если бы оно отсутствовало вовсе, а именно:
0
.
Обратите внимание, что здесь все происходит точно так же, как если Вы
назначаете пустую стргоку явно как значение соответствующего поля с помощью
вызовов INSERT
или UPDATE
.
Столбцы TIMESTAMP
будут установлены только к текущей дате и
времени, если для столбца имеется значение NULL
, или (только для
первого столбца TIMESTAMP
) если столбец типа
TIMESTAMP
не учтен в списке полей, когда такой список определен.
Если входная строка имеет слишком много полей, лишние поля игнорируются.
LOAD DATA INFILE
расценивает весь ввод как строки, так что Вы
не можете использовать числовые значения для столбцов типов ENUM
или SET
, как Вы можете это делать инструкциями
INSERT
. Все значения ENUM
и SET
должны
быть определены как строки!
Если Вы используете C API, Вы можете получать
информацию относительно запроса, вызывая функцию mysql_info()
когда запрос LOAD DATA INFILE
обработан. Формат информационной
строки показывается ниже:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Предупреждения происходят при тех же самых обстоятельствах, что и с
командой INSERT
(подробности в разделе
"8.3 Синтаксис INSERT
"), за
исключением того, что LOAD DATA INFILE
также генерирует
предупреждения, когда имеется слишком мало или слишком много полей во входной
строке. Предупреждения не сохранены где-нибудь. Число предупреждений может
использоваться только как индикация, если все пошло нормально. Если Вы
получаете предупреждения и хотите знать точно, почему Вы их получили, один
способ сделать это состоит в том, чтобы использовать SELECT ... INTO
OUTFILE
в другой файл и сравнить его с первоначальным входным файлом.
Если Вы нуждаетесь в LOAD DATA
, чтобы читать из канала, Вы
можете использовать следующий прием:
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
Если Вы используете версию MySQL до 3.23.25, Вы можете делать
вышеупомянутое только с помощью LOAD DATA LOCAL INFILE
.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |