есть достаточно большое количество statements, которые после запуска не могут быть rollback. список: для 5.0, для 5.1, то есть mysql не является ACID compliant, хотя оно заявлено.
drop table if exists temp_test_one, temp_test_two;
begin;
create table temp_test_one (a int, b int);
rollback;
-- fail here, create table caused implicit commit
create table temp_test_one (a int);
begin;
alter table test1 drop b;
rollback;
-- fail here, because alter table also caused implicit commit
alter table test1 drop b;
по непонятным для меня причинам, второе поле типа timestamp не может принимать значение now() при вставке, что делает возможным создание поля created только с помощью триггера. зато первое поле такого типа по умолчанию апдейтится при каждом обновлении записи. вот такая долбаная магия.
-- fail here, error: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause (WHY?)
create table temp_test_two (created timestamp default now(), updated timestamp default now());
-- fail here because first timestamp column have default now()
create table temp_test_two (updated timestamp, created timestamp default now());
create table temp_test_two (updated timestamp, created timestamp);
-- now updated column being updated on any update
триггеры может создавать только пользователь с правами super (вроде, в 5.1 они это поправили)
-- fail here if you don't have super privilege (5.0)
create trigger temp_test_two_bcreate before insert on temp_test_two for each row set new.created = now();
чюваки из mysql до сих пор не смогли написать нормального парсера, чтобы разграничивать внутренности процедур от остального sql кода.
-- fail because you don't set delimiter (stupid mysql parser can't recognize trigger end without separation delimiters inside trigger and outside)
create trigger contact_aupdate after update on contact
for each row begin
if new.contact_auth = 'ok' then
update domain set domain_authenticated = true, domain_state = 'auth' where auth_contact_id = new.contact_id;
end if;
end;
теперь про перл
mysql не может запускать сразу два statement в одном do; если сделать fork, то придется создавать новое соединение, так как старое привязано к process id.
my $dbh = DBI->connect;
my $pid = fork;
if ($pid) {
# failed because you can't launch two statements at same time
$dbh->do ('drop table if exists temp_test_one; drop table if exists temp_test_two; ');
} else {
# failed because cloned dbh doesn't work
$dbh->do ('drop table if exists temp_test_one, temp_test_two;');
}
короче, если нет возможности использовать что–то другое, то можно, иначе — нужно как можно быстрее избавляться от mysql в пользу postgresql и/или sqlite.
1 comment:
> по непонятным для меня причинам, второе
> поле типа timestamp не может принимать
> значение now() при вставке, что делает
> возможным создание поля created только
> с помощью триггера. зато первое поле
> такого типа по умолчанию апдейтится при
> каждом обновлении записи. вот такая
> долбаная магия.
это вполне документировано. http://dev.mysql.com/doc/refman/5.0/en/timestamp.html
можно сделать так:
create table x (
y int,
created timestamp not null default '0000-00-00 00:00:00',
updated timestamp default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP );
а потом делать:
INSERT INTO x (y,created) VALUES (1,NULL);
Это помогает.
Post a Comment