[Dbix-class] emulating (or using) MySQL's INSERT...ON DUPLICATE KEY UPDATE...
Mark Hedges
hedges at ucsd.edu
Fri Jun 23 06:22:51 CEST 2006
MySQL has a mod to INSERT where you can do:
INSERT key_field = '$key_value',
some_field = 1
ON DUPLICATE KEY UPDATE some_field = some_field + 1
In a multi-connection system, this is really handy for the
initial insert of some counter row if an attempt at update
said no rows affected, because then concurrent insert attempts
will do the right thing.
It's also useful in later aggregation of counters if I don't
know whether I already have a row or not.
I would have to do this I guess:
my $rs = Schema->resultset('Thing');
my $row = $rs->find( $key_value );
if ($row) {
$row->some_field( $row->some_field + 1 );
$row->update;
}
else {
$rs->create({ key_field => $key_value, some_field => 1 });
}
Because I assume (?) this wouldn't work:
$rs->update_or_create({
key_field => $key_value,
some_field => \q{ some_field + 1 },
});
Or would it? Oh wild, this SQL:
INSERT INTO thing SET some_field = some_field + 1;
does work if some_field is not null default 0. Crazy.
I see from ResultSet.pm that it does try to find the row first,
and then it decides whether to update or create.
So in a multi-connection (possibly multi-server) environment,
update_or_create cannot be used reliably.
For the purpose of my later aggregation it will probably work fine.
This is just food for though I guess, whether it's worth it or
not to attempt to extend vendor-specific statements to that
level of the DBIC code.
Mark
More information about the Dbix-class
mailing list