суббота
Интересный баг mysql

По долгу службы пришлось мне отправиться в длительную поездку. Компьютер с собой не возьмешь, и поэтому приспичило меня залить дамп базы Mysql на ноутбук с OpenSuSe 11.0. Dump отказался заливаться, ругнулся вот так:
ERROR 1221 (HY000) at line 3: Incorrect usage of UNION and INTO
Код хранимой функции был чистый, давным-давно вылизанный и ошибок в нем не было. Выяснилось, что на старых версиях mysql может не работать вот такая конструкция:
select 1 into @`avar` from (select 1 union select 1) `a`;
хотя сам запрос:
select 1 from (select 1 union select 1) `a`;
синтаксически правильный и имеет право на жизнь. Баг в конце концов поправили (подробности здесь), но в стандартных репозиториях OpenSuSe 11.0 (OSS, Non-OSS, Debug и Updates) версия mysql осталась старая, с багом.
Проблема лечится подключением репозитория MySQL и обновлением до последней версии сервера mysql.
Ярлыки: Linux, MySQL, Интересное
четверг
MySQL и защита от удаления записей в таблицах
Однажды мне понадобилась защита от удаления записей в таблице. Естественно, на триггере BEFORE DELETE, чтобы уж наверняка все работало. В привычном мне Oracle такая задача решается очень просто, с вызовом raise_application_error внутри триггера. Но как оказалось, в MySQL такая задача решается через жоп использование несуществующего поля в какой-нибудь таблице. Вот пример:
delimiter |
CREATE TRIGGER my_table_bd
BEFORE DELETE ON my_table
FOR EACH ROW
begin
declare v int;
if ifnull(old.status,0) > 0 then
select antarktida
into v
from logs u
where africa = 'asia';
end if;
end|
delimiter ;
Полей antarktida, africa в таблице logs нет, поэтому при срабатывании триггера происходит ошибка. Причем ошибка выскочит, если ifnull(old.status,0) > 0. Такая конструкция выглядит ужасно (костыль он и есть костыль), но работает 100%. И похоже, это единственный способ запретить удаление из таблицы.
Ярлыки: MySQL
понедельник
Экспорт баз MySQL
mysqldump -u username -p db_name --routines --extended-insert >dump.sql
воскресенье
Как получить список дат в mysql
Однажды мне потребовалось получить список дат на каждый день 2009 года. Как оказалось, в mysql такой список получить очень просто.
Для этого нужна всего лишь любая таблица, в которой есть не меньше 365 строк. У меня такая таблица была, и называется она games. Скрипт выглядит так:
SET @rownum:=0;
select adddate('2008-12-31',interval @rownum:=@rownum+1 DAY) next_date from games limit 0,365;
четверг
Как сбросить пароль в mysql
1. Останавливаем mysqld:
/etc/init.d/mysqld stop
2. Запускаем mysqld без проверки прав доступа:
mysqld_safe --skip-grant-tables &
3. Заходим под рутом и перебиваем пароль:
mysql -u root -D mysql
mysql> update user set password=password('new_password') where user='root';
4. Обновляем права доступа:
flush privileges;
5. Выходим, убиваем mysqld и запускаем его снова:
mysql> exit;
/etc/init.d/mysqld stop
/etc/init.d/mysqld start
Ярлыки: Linux, MySQL, Полезное