- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Основы программирования в Linux - Нейл Мэтью
Шрифт:
Интервал:
Закладка:
#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
int main(int argc, char *argv[]) {
MYSQL my_connection;
mysql_init(&my_connection);
if (mysql_real_connect(&my_connection, "localhost", "rick",
"I do not know", "foo", 0, NULL, 0)) {
printf("Connection successn");
mysql_close(&my_connection);
} else {
fprintf(stderr, "Connection failedn");
if (mysql_errno(&my_connection)) {
fprintf(stderr, "Connection error %d: %sn",
mysql_errno(&my_connection), mysql_error(&my_connection));
}
}
return EXIT_SUCCESS;
}
Вы смогли легко решить проблему, устранив перезапись вашего дескриптора подключения результатом, возвращаемым при аварийном завершении mysql_real_connect. И кроме того, это отличный пример еще одного способа применения структур дескрипторов подключения. Вы можете вызвать ошибку, выбрав некорректное имя пользователя или пароль, и получите код ошибки, подобный предлагаемому монитором mysql:
$ ./connect2
Connection failed
Connection error 1045: Access denied for user: '[email protected]' (Using password: YES)
$
Выполнение SQL-операторов
Теперь, когда вы можете подключаться к вашей базе данных и корректно обрабатывать ошибки, самое время дать вашей программе реальную работу. У основной функции API, предназначенной для выполнения операторов языка SQL, подходящее имя.
int mysql_query(MYSQL *connection, const char *query);
He слишком сложная? Эта подпрограмма принимает указатель на дескриптор подключения и несколько, хочется надеяться, корректных SQL-операторов в виде текстовой строки (без завершения каждого из них точкой с запятой, как в мониторе mysql). В случае удачного завершения возвращается ноль. Вторую подпрограмму mysql_real_query можно применять при запросе двоичных данных, но в этой главе мы используем только подпрограмму mysql_query.
SQL-операторы, не возвращающие данныхДля простоты начнем с рассмотрения нескольких SQL-операторов, которые не возвращают данные: UPDATE, DELETE и INSERT.
Еще одна важная функция, которую мы рассмотрим, проверяет количество строк, затронутых запросом:
my_ulonglong mysql_affected_rows(MYSQL *connection);
Первое, что вы, вероятно, заметили в этой функции, — очень необычный тип возвращаемых данных. Из соображений переносимости применяется беззнаковый (unsigned) тип. Когда используется функция printf, рекомендуется приводить его к типу unsigned long (длинное беззнаковое) со спецификатором формата %lu. Эта функция возвращает количество строк, измененных предварительно выполненным запросом UPDATE, INSERT или DELETE. Возвращаемое значение, используемое в MySQL, может вас, озадачить, если у вас есть опыт работы с другими базами данных SQL. СУРБД MySQL возвращает количество строк, действительно измененных обновлением, в то время как многие другие СУБД будут считать запись измененной просто потому, что она соответствует одному из условий WHERE.
В основном в случае функций mysql_ возврат 0 означает отсутствие измененных строк, а положительное значение указывает на реальный результат, обычно количество строк, затронутых оператором.
Сначала следует создать таблицу children в вашей базе данных foo, если вы еще не сделали этого. Удалите (с помощью команды drop) любую существующую таблицу, чтобы быть уверенным в том, что вы имеете дело с чистым определением таблицы, и повторно отправьте идентификаторы, применяемые в столбце AUTO_INCREMENT.
$ mysql -u rick -p foo
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
mysql> DROP TABLE children;
Query OK, 0 rows affected (0.58 sec)
mysql> CREATE TABLE children (
-> childno int(11) AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> fname varchar(30),
-> age int
-> );
Query OK, 0 rows affected (0.09 sec)
mysql>
Теперь добавьте программный код в файл connect2.c, для того чтобы вставить новую строку в вашу таблицу. Назовите эту новую программу insert1.с. Учтите, что разбиение оператора на несколько строк объясняется физической шириной страницы; обычно вы не должны разбивать реальный SQL-оператор, если он не слишком длинный, в этом случае можно применить символ / в конце строки для переноса оставшейся части SQL-оператора на следующую строку.
#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
int main(int argc, char *argv[]) {
MYSQL my_connection;
int res;
mysql_init(&my_connection);
if (mysql_real_connect(&my_connection, "localhost",
"rick", "secret", "foo", 0, NULL, 0)) {
printf("Connection successn");
res = mysql_query(&my_connection,
"INSERT INTO children(fname, age) VALUES('Ann', 3)");
if (!res) {
printf("Inserted %lu rowsn",
(unsigned long)mysql_affected_rows(&my_connection));
} else {
fprintf(stderr, "Insert error %d: %sn",
mysql_errno(&my_connection), &mysql_error(&my_connection));
}
mysql_close(&my_connection);
} else {
fprintf(stderr, "Connection failedn");
if (mysql_errno(&my_connection)) {
printf(stderr, "Connection error %d: %sn",
mysql_errno(&my_connection), mysql_error(&my_connection));
}
}
return EXIT_SUCCESS;
}
Как и ожидалось, одна строка добавлена.
Теперь измените код, чтобы включить UPDATE вместо INSERT, и посмотрите на сообщение об измененных строках.
mysql_errno(&my_connection), mysql_error(&my_connection));
}
}
res = mysql_query(&my_connection,
"UPDATE children SET AGE = 4 WHERE fname = 'Ann'");
if (!res) {
printf("Updated %lu rowsn",
(unsigned long)mysql_affected_rows(&my_connection));
} else {
fprintf (stderr, "Update error %d: %sn",
mysql_errno(&my_connection), mysql_error(&my_connection));
}
Назовите эту программу update1.c. Она пытается задать возраст 4 года для всех детей с именем Ann.
Предположим, что ваша таблица children содержит следующие данные:
mysql> SELECT * from CHILDREN;
+---------+--------+-----+
| childno | fname | age |
+---------+--------+-----+
| 1 | Jenny | 21 |
| 2 | Andrew | 17 |
| 3 | Gavin | 9 |
| 4 | Duncan | 6 |
| 5 | Emma | 4 |
| 6 | Alex | 15 |
| 7 | Adrian | 9 |
| 8 | Ann | 3 |
| 9 | Ann | 4 |
| 10 | Ann | 3 |
| 11 | Ann | 4 |
+---------+--------+-----+
11 rows in set (0.00 sec)
В вашей таблице есть четыре ребенка с именем Ann. Вы можете рассчитывать на то, что при выполнении программы update1 количество измененных строк будет равно четырем, т.е. числу строк, отбираемых по условию WHERE. Но если вы выполните программу, то увидите отчет программы об изменении только двух строк, поскольку учитываются только те строки, данные которых действительно нуждались в корректировке. Можно выбрать более традиционный вариант отчета, используя флаг CLIENT_FOUND_ROWS в функции mysql_real_connect:
if (mysql_real_connect(&my_connection, "localhost",
"rick", "secret", "foo", 0, NULL, CLIENT_FOUND_ROWS)) {
Если восстановить данные в вашей базе данных и затем выполнить программу с приведенным изменением, она сообщит о четырех измененных строках.
Последняя странность функции mysql_affected_rows проявляется при удалении информации из базы данных. Если вы удаляете данные с помощью условия WHERE, mysql_affected_rows вернет ожидаемое вами количество удаленных строк. Но если в операторе DELETE нет условия WHERE, будут удалены все строки, но в сообщении программы о количестве строк, затронутых запросом, будет указан ноль. Это происходит потому, что MySQL оптимизирует удаление всех строк, заменяя многократные построчные удаления.
На подобное поведение не влияет флаг CLIENT_FOUND_ROWS.
Что же вы вставили?Существует небольшая, но важная особенность вставки данных. Ранее мы упоминали столбец типа AUTO_INCREMENT, в который MySQL автоматически вставляет идентификаторы. Это свойство весьма полезно, особенно при наличии нескольких пользователей.
Рассмотрим определение таблицы еще раз:
CREATE TABLE children (
childno INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
fname VARCHAR(30),
age INTEGER
);
Как видите, столбец childno— поле типа AUTO_INCREMENT. Это замечательно, но когда вы вставили строку, как узнать, какой номер присвоен ребенку, чье имя вы только что вставили?

