Информация
На главную Главная

Мой t-cards.ru
Войти Войти
Зарегистрироваться Регистрация

Разное
Форум Форум
Вернуться Форумы на t-cards.ru> Hard"n"Soft
Логин
Пароль
Регистрация Участники Поиск >> FAQ


Сообщения в теме: "Perl + mysql. Полезные советы...."
25.12.2007 03:06
Admin

Регистрация: 19.04.2006
Проживание: Калуга
Сообщения: 57
По умолчаниюPerl + mysql. Полезные советы.

Занялся написанием одного достаточного большого проекта на perl + mysql. Большую важность играет структура таблиц БД, нормализация и целостность. Существует множество INSERT запросов в таблицы с множеством уникальных связок по полям. Каждая такая таблица имеет инкрементальное поле.
Задача сводится к тому, чтобы в результате каждого INSERTa знать добавилось ли поле, а ещё лучше - знать инкрементальное значение последней записи.
Казалось бы всё просто - выполняем метод do интерфейса с переданным в него параметром строки запроса и после этого имеем свойство mysql_insertid у того же интерфейса, которое если != 0 указывает на добавленную строку.
Но, как показала практика, такой метод весьма опасен. Во-первых, свойствао mysql_insertid доступно только для чтения, мы не можем его обнулять, а, во-вторых, - следующий неудачный INSERT после удачного будет содержать инкрементальное значение последнего удачного. Как вариант - переподключаться к базе после каждого INSERT. Да да, я тоже думаю что это маразм, поэтому предлагаю свой простой способ проверки на ошибки.
Сначала откажемся от метода do, будем действовать как с любым запросом на получение данных - сперва prepare, затем execute:

my $dbh = DBI->connect(...);
my $sth = $dbh->prepare(\"INSERT ...\");
$sth->execute();

после этого у интерфейса запроса $sth появится свойство rows, которое будет 0 если не добавлена ни одна строка или > 0 в зависимости от добавленных строк.
В итоге проверка сводится к простому:

return $dbh->{mysql_insertid} if ($sth->rows == 1 );
return 0;

для инсерта одной строки

Вот и всё.. Если баян - сильно не бейте, видел в инете другие способы, некоторые лочат для этого таблицы )) Такого способа не находил...

25.12.2007 12:51
Admin

Регистрация: 05.10.2005
Проживание: Москва
Сообщения: 284
По умолчаниюPerl + mysql. Полезные советы.

Очень странно, вот например функция last_insert_id() возвращает последний вставленный id в пределах соединения, т.е. не надо опасаться, что сюда другие попадут.
И в случае, если INSERT завершается с ошибкой, эта функция возвращает 0.

P.S. Я не помню правда, начиная с какой версии она доступна, проверь.
25.12.2007 22:39
Admin

Регистрация: 19.04.2006
Проживание: Калуга
Сообщения: 57
По умолчаниюPerl + mysql. Полезные советы.

Знаю, читал.
Вот только у меня mod_perl,а в нем мона сделать так, чтоб соединение было одно.

да и делать нечто подобное:
my $sth = $dbh->prepare(\\\"select last_insert_id() as id\\\");
$sth->execute;
$id = $sth->fetchrow_hashref->{\\\'id\\\'};

каждый раз при необходимости узнать значение несколько неудобно и наверно накладно.