Сохранение данных в базе данных (несколько таблиц)
Область применения:Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
Наборы данных и связанные классы являются устаревшими технологиями платформа .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти во время отключения приложений от базы данных. Они особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных оказались очень успешными, мы рекомендуем новым приложениям .NET использовать Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей, и он имеет более простой интерфейс программирования.
Одним из наиболее распространенных сценариев в разработке приложений является отображение данных на форме в приложении Windows, изменение этих данных и отправка обновленных данных обратно в базу данных. Это пошаговое руководство описывает создание формы, отображающей данные из двух связанных таблиц, правку записей и сохранение изменений в базе данных. В данном примере используются таблицы Customers и Orders из учебной базы данных «Борей».
Вы можете сохранить данные из приложения в базе данных, вызвав метод Update адаптера таблицы. При перетаскивании таблиц из окна источников данных в форму автоматически добавляется код, необходимый для сохранения данных. Для любых дополнительных таблиц, добавленных в форму, требуется ручное добавление этого кода. Это пошаговое руководство описывает добавление кода для сохранения обновлений из нескольких таблиц.
В данном пошаговом руководстве представлены следующие задачи.
- Создание и настройка источника данных в приложении с помощью мастера настройки источника данных.
- Настройка элементов управления в окне источников данных. Дополнительные сведения см. в разделе «Настройка элемента управления для создания при перетаскивании из окна источников данных».
- Создание элементов управления с привязкой к данным с помощью перетаскивания элементов из окна Источники данных на форму.
- Изменение нескольких записей в каждой таблице в наборе данных.
- Изменение кода для отправки обновленных данных в наборе данных обратно в базу данных.
Необходимые компоненты
В этом пошаговом руководстве используется SQL Server Express LocalDB и пример базы данных Northwind.
- Если у вас нет SQL Server Express LocalDB, установите его на странице скачивания SQL Server Express или с помощью Установщика Visual Studio. В установщике Visual Studio можно установить SQL Server Express LocalDB как часть рабочей нагрузки хранилища данных и обработки или как отдельный компонент.
- Установите пример базы данных Northwind, выполнив следующие действия.
- В Visual Studio откройте окно обозреватель объектов SQL Server. (SQL Server обозреватель объектов устанавливается как часть рабочей нагрузки хранилища данных и обработки в Visual Studio Installer.) Разверните узел SQL Server. Щелкните правой кнопкой мыши экземпляр LocalDB и выберите новый запрос. Откроется окно редактора запросов.
- Скопируйте скрипт Northwind Transact-SQL в буфер обмена. Этот скрипт T-SQL создает базу данных Northwind с нуля и заполняет ее данными.
- Вставьте скрипт T-SQL в редактор запросов и нажмите кнопку «Выполнить «. Через некоторое время запрос завершает работу и создается база данных Northwind.
Создание приложения Windows Forms
Создайте проект приложения Windows Forms для C# или Visual Basic. Присвойте проекту имя UpdateMultipleTablesWalkthrough.
Создание источника данных
На этом шаге Мастер настройки источника данных используется для создания источника данных из базы данных Northwind. Для создания подключения необходимо иметь доступ к учебной базе данных «Борей». Сведения о настройке образца базы данных Northwind см. в разделе «Практическое руководство. Установка примеров баз данных».
- В меню Данные выберите пункт Показать источники данных. Открывается окно Источники данных.
- В окне Источники данных выберите Добавить новый источник данных, чтобы запустить Мастер настройки источника данных.
- На экране «Выбор типа источника данных» выберите «База данных» и нажмите кнопку «Далее«.
- На экране выбора данных Подключение ion выполните одно из следующих действий:
- Если подключение к учебной базе данных Northwind доступно в раскрывающемся списке, то выберите его. или
- Выберите Новое подключение для открытия диалогового окна Добавить/изменить подключение.
- Если для базы данных требуется пароль, выберите параметр для включения конфиденциальных данных и нажмите кнопку «Далее«.
- В файле конфигурации приложения в строка подключения нажмите кнопку «Далее«.
- На экране «Выбор объектов базы данных» разверните узел «Таблицы«.
- Выберите таблицы «Клиенты и заказы«, а затем нажмите кнопку «Готово«. Объект NorthwindDataSet добавляется в проект, и таблицы отображаются в окне Источники данных.
Настройка созданных элементов управления
В этом пошаговом руководстве данные в Customers таблице отображаются в макете сведений , где данные отображаются в отдельных элементах управления. Данные из Orders таблицы отображаются в макете сетки , отображаемом в элементе DataGridView управления.
Установка типа удаления для элементов в окне «Источники данных»
- В окне «Источники данных» разверните узел «Клиенты«.
- На узле «Клиенты» выберите «Сведения» из списка элементов управления, чтобы изменить элемент управления таблицей «Клиенты» на отдельные элементы управления. Дополнительные сведения см. в разделе «Настройка элемента управления для создания при перетаскивании из окна источников данных».
Создание формы, привязанной к данным
Вы можете создавать элементы управления с привязкой к данным с помощью перетаскивания элементов из окна Источники данных на форму.
- Перетащите главный узел Customers из окна Источники данных на форму Form1. Привязанные к данным элементы управления с метками описания отображаются на форме вместе с панелью инструментов (BindingNavigator) для перемещения по записям. Объект NorthwindDataSet, CustomersTableAdapter BindingSourceи BindingNavigator отображается в области компонентов.
- Перетащите связанный узел Заказы из окна Источники данных на Form1.
Примечание. Связанный узел Заказы расположен под столбцом Факс и является дочерним для узла Клиенты.
Добавление кода для обновления базы данных
Вы можете обновить базу данных, вызвав методы Update адаптеров таблицы Клиенты и Заказы. По умолчанию обработчик событий для кнопкиBindingNavigator «Сохранить» в код формы добавляется для отправки обновлений в базу данных. Эта процедура изменяет код для отправки обновлений в правильном порядке. Это устраняет возможность возникновения ошибок целостности ссылок. Этот код также реализует обработку ошибок, упаковывая вызов обновления в блок try-catch. Вы можете изменить этот код в соответствии с потребностями своего приложения.
Для ясности в этом пошаговом руководстве не используется транзакция. Однако если вы обновляете две или более связанные таблицы, включите всю логику обновления в транзакцию. Транзакция — это процесс, обеспечивающий успешное выполнение всех связанных изменений в базе данных до фиксации любых изменений. Дополнительные сведения см. в разделе «Транзакции и параллелизм».
Добавление логики обновления в приложение
- Нажмите кнопку «Сохранить » на вкладке BindingNavigator. Откроется редактор кода обработчику bindingNavigatorSaveItem_Click событий.
- Замените код в обработчике событий на вызов методов Update связанных адаптеров таблицы. Следующий код сначала создает три временные таблицы данных для хранения обновленной информации для каждого DataRowState (Deleted, Added и Modified). Обновления выполняются в правильном порядке. Код должен выглядеть следующим образом:
this.Validate(); this.ordersBindingSource.EndEdit(); this.customersBindingSource.EndEdit(); NorthwindDataSet.OrdersDataTable deletedOrders = (NorthwindDataSet.OrdersDataTable) northwindDataSet.Orders.GetChanges(DataRowState.Deleted); NorthwindDataSet.OrdersDataTable newOrders = (NorthwindDataSet.OrdersDataTable) northwindDataSet.Orders.GetChanges(DataRowState.Added); NorthwindDataSet.OrdersDataTable modifiedOrders = (NorthwindDataSet.OrdersDataTable) northwindDataSet.Orders.GetChanges(DataRowState.Modified); try < // Remove all deleted orders from the Orders table. if (deletedOrders != null) < ordersTableAdapter.Update(deletedOrders); >// Update the Customers table. customersTableAdapter.Update(northwindDataSet.Customers); // Add new orders to the Orders table. if (newOrders != null) < ordersTableAdapter.Update(newOrders); >// Update all modified Orders. if (modifiedOrders != null) < ordersTableAdapter.Update(modifiedOrders); >northwindDataSet.AcceptChanges(); > catch (System.Exception ex) < MessageBox.Show("Update failed"); >finally < if (deletedOrders != null) < deletedOrders.Dispose(); >if (newOrders != null) < newOrders.Dispose(); >if (modifiedOrders != null) < modifiedOrders.Dispose(); >>Me.Validate() Me.OrdersBindingSource.EndEdit() Me.CustomersBindingSource.EndEdit() Dim deletedOrders As NorthwindDataSet.OrdersDataTable = CType( NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Deleted), NorthwindDataSet.OrdersDataTable) Dim newOrders As NorthwindDataSet.OrdersDataTable = CType( NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Added), NorthwindDataSet.OrdersDataTable) Dim modifiedOrders As NorthwindDataSet.OrdersDataTable = CType( NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Modified), NorthwindDataSet.OrdersDataTable) Try ' Remove all deleted orders from the Orders table. If Not deletedOrders Is Nothing Then OrdersTableAdapter.Update(deletedOrders) End If ' Update the Customers table. CustomersTableAdapter.Update(NorthwindDataSet.Customers) ' Add new orders to the Orders table. If Not newOrders Is Nothing Then OrdersTableAdapter.Update(newOrders) End If ' Update all modified Orders. If Not modifiedOrders Is Nothing Then OrdersTableAdapter.Update(modifiedOrders) End If NorthwindDataSet.AcceptChanges() Catch ex As Exception MsgBox("Update failed") Finally If Not deletedOrders Is Nothing Then deletedOrders.Dispose() End If If Not newOrders Is Nothing Then newOrders.Dispose() End If If Not modifiedOrders Is Nothing Then modifiedOrders.Dispose() End If End TryТестирование приложения
- Нажмите клавишу F5.
- Внесите изменения в данные одной или нескольких записей в каждой таблице.
- Выберите кнопку Сохранить.
- Проверьте значения в базе данных и убедитесь, что изменения были сохранены.
См. также
Как сохранить таблицы одной базы данных в MySQL и перенести в другую?
Имеется две базы данных (database) в MySQL. Названия у них разные, но структура таблиц одинаковая. Как сделать бэкап одной базы и залить данные в другую? Пожалуйста, с описанием команд, что и как. Заранее спасибо.
Отслеживать
51.2k 86 86 золотых знаков 266 266 серебряных знаков 505 505 бронзовых знаков
задан 24 янв 2011 в 15:45
886 2 2 золотых знака 15 15 серебряных знаков 48 48 бронзовых знаков2 ответа 2
Сортировка: Сброс на вариант по умолчанию
mysqldump -u -p | mysql -u -pПервая команда — mysqldump. Собственно, она выводит содержимой указанной базы данных в виде текста. Вторая команда — банально читает из стандартного потока дамп (в том же формате, в котором его выдаёт mysqldump, что удобно!) и заливает его в указанную БД.
Соответственно, сцепили их конвейером — и всё получилось. Можно через промежуточный файл, если больше нравится.
Отслеживать
ответ дан 24 янв 2011 в 17:37
4,508 21 21 серебряный знак 29 29 бронзовых знаковЕщё идея на всякий случай.
Есть такой секретный синтаксис (никому о нём не рассказывайте!):
CREATE TABLE AS SELECT * FROM ;Если помнить, что имена таблиц можно указывать в виде имя_БД.имя_таблицы , то таким образом несложно перенести одну таблицу в другую БД.
Однако, тут не получится перенести все таблицы за один ход. Боюсь, что без хранимых процедур, на чистом SQL, эта задача не имеет решения.
Как сохранить Excel/DataTable таблицу в БД (MS SQL Server)?
Есть таблицы DataTable (Excel) с различным количеством столбцов, строк, а также любыми вариантами типов столбцов.
Как оптимально сохранять таблицу в базу данных (MS SQL Server) ?
чтобы сохранить:
— названия столбцов и их типы
— все строки, ячейки этих таблиц, данные в общем.Четкого формата таблиц нет. Всегда это набор столбцов от 1 до N. С данными от 1 до M строк.
Создавать таблицу в БД с 100 allownull столбцами вида (col1, col2, . col100) и заполнять ее начальные стоблцы ,а другие пропускать если таблица меньше — не хочется. Как-то не красиво.
Сохранять каждую ячейку по отдельности — это не оптимально, это занимает огромное количество времени чтобы сохранить и считать.
Вот думаю преобразовать таблицу к простому CSV формату и сохранять как текст, потом его обратно превращать в DataTable.
Может какие еще варианты есть?
- Вопрос задан более трёх лет назад
- 1849 просмотров
Комментировать
Решения вопроса 1
Станислав Макаров @Nipheris Куратор тега C#
> Четкого формата таблиц нет.
Значит реляционная модель как таковая вам не подходит. Тут есть два варианта:
1) Entity-Attribute-Value (возможно это вы и имели в виду под «Сохранять каждую ячейку по отдельности», ну тогда решать вам. Работать будет разумеется медленнее, чем нормальная таблица, но у вас же нет схемы, ничего не поделаешь)
2) JSON/XML. Тут уж либо поля типа XML, либо привет документно-ориентированная СУБД.Второй вариант годится, если выборки внутри таблицы не нужны или нужны редко (раз уж вы заговорили про CSV). Если нужны часто — то тогда EAV самое оно.
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ответы на вопрос 1
Арман Токсимбаев @toxicdream
Дружелюбный и доверчивый социопатМожет разные таблицы (с разной структурой) хранить/импортировать в разные таблицы => MyCoolTable001, MyCoolTable002 .
А в крайнем случае еще создать метатаблицу в которой хранить что MyCoolTable001 был импортирован из D:\Важные данные\111.xlsx в 2015-05-06 04:34:57.Как сохранить таблицу в sql
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;
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;
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;
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;
SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
mysql> select * from table LIMIT 5,10; # Вернуть строки 6-15
Если один параметр задан, он указывает максимальное число строк:
mysql> select * from table LIMIT 5; # Вернуть первые 5 строк
- Сам символ ESCAPED BY
- Первый символ в FIELDS TERMINATED BY
- Первый символ в LINES TERMINATED BY
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM test_table;
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;
mysql> select table1.* from table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id is NULL;
A LEFT JOIN B USING (C1,C2,C3. )
Определено, чтобы быть семантически идентичным выражению ON :
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3.
Вот некоторые примеры:
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;
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 [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 , чтобы выяснить.
- Любой столбец, для которого значение явно не задано, будет установлен в значение по умолчанию. Например, если Вы определяете список столбцов, который не называет все столбцы в таблице, неназванные столбцы будут установлены в их значения по умолчанию. Задание значений по умолчанию описано в разделе «7.3 Синтаксис 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);
Если Вы используете 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 [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 работают как обычной.
- Вы можете использовать функцию C API mysql_info() , чтобы получить информацию относительно запроса. Подробности в разделе «8.3 Синтаксис INSERT «.
- Чтобы гарантировать, что модификации регистрируются и могут использоваться, чтобы пересоздать первоначальные таблицы, MySQL не будет позволять параллельные вставки в течение выполнения INSERT . SELECT .
Вы можете, конечно, также использовать REPLACE вместо INSERT , чтобы перезаписать старые строки.
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 не использует всю память для отсроченной очереди.
- Поток драйвера обнаружится в списке процесса MySQL с меткой 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 :
Вы можете рассматривать эти переменные, выдавая инструкцию SHOW STATUS или выполняя команду mysqladmin extended-status .Переменная Значение Delayed_insert_threads Число обработчиков потоков Delayed_writes Число строк, вставленных с помощью INSERT DELAYED Not_flushed_delayed_rows Число строк, ждущих записи
Обратите внимание, что INSERT DELAYED медленнее, чем нормальная INSERT, если таблица сейчас не используется. Имеется также дополнительная нагрузка для сервера, чтобы обработать отдельный поток для каждой таблицы, на которой Вы используете INSERT DELAYED . Это означает, что Вы должны использовать INSERT DELAYED только тогда, когда Вы, действительно, уверены, что нуждаетесь в этом!
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 [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 TABLE table_name
В версии 3.23 TRUNCATE TABLE отображен на вызов COMMIT; DELETE FROM table_name . Подробности в разделе «8.6 Синтаксис DELETE «.
Разница между TRUNCATE TABLE и DELETE FROM .. :
- Truncate удаляет и пересоздает таблицу, что намного быстрее, чем удаление строк одну за другой.
- Не транзакционно-безопасно: Вы получите ошибку, если имеете активную транзакцию или активную блокировку таблицы.
- Не возвращает число удаленных строк.
- Пока файл определения таблицы table_name.frm корректен, таблица может быть пересоздана, даже если данные или индексный файл повреждены.
TRUNCATE представляет собой Oracle-расширение языка SQL.
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 [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 действовать следующим образом при чтении ввода:
- Найти границы строки по newlines.
- Разделить строки на поля через символы табуляции.
- Не ожидать, что поля будут заключены внутрь любых символов цитирования.
- Интерпретировать местонахождения позиций табуляции, newline или \ предшествующего \ как литеральные символы, которые являются частью значений поля.
SELECT . INTO OUTFILE по умолчанию должен действовать следующим образом при записи вывода:
- Записать позиции табуляции между полями.
- Не включать поля внутрь любых символов цитирования.
- Использовать \ , чтобы выйти из позиций табуляции, newline или символов \ , которые происходят внутри значений поля.
- Записать newlines в конце строк.
Обратите внимание, что, чтобы писать 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 [OPTIONALLY] ENCLOSED BY .
- Первый символ значений FIELDS TERMINATED BY и LINES TERMINATED BY .
- ASCII 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 и пустые строки в таблице, когда они записаны в файл потому, что и то и другое пишется как как пустые строки. Если Вы должны при чтении файла иметь возможность разобраться что есть что, не следует применять фиксированный формат строки.
- Строки фиксированной длины ( FIELDS TERMINATED BY и FIELDS ENCLOSED BY вместе пустые) в сочетании со столбцами BLOB или TEXT .
- Если Вы определяете один разделитель, который является префиксом другого, команда LOAD DATA INFILE не будет способна интерпретировать ввод правильно. Например, следующее предложение FIELDS проблемное:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
Следующий пример загружает все столбцы таблицы 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 .
- Для типов даты и времени, столбец установлен к соответствующему нулю для типа. Подробности в разделе «5.2 Типы Date и Time».
Обратите внимание, что здесь все происходит точно так же, как если Вы назначаете пустую стргоку явно как значение соответствующего поля с помощью вызовов 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 .
