以前ちゃちゃっと作ったプログラムはMySQLのトランザクションを使っている。

START TRANSACTION;
SELECT ~;
INSERT ~;
COMMIT;

万が一うまくいかなかった場合に備えて、いくつかのエラー制御も実装。

で、なぜだかINSERTで書き込まれるはずのデータが書き込まれなかった。
エラーはなし。
どうしてもうまくいかない。

そこで、トランザクションをあきらめて、テーブルロックを使うことにした。

LOCK TABLES table WRITE;
SELECT ~;
INSERT ~;
UNLOCK TABLES;

エラーはないが、やっぱりうまくいかない。
SQL文を間違えたか…。いや、それならエラーが出るはず…。

念のため、プログラムが生成したSQL文を出力して、コピペで実行。
動いた!

やっぱりプログラムがおかしい。

PerlからDBIを使ってMySQLにアクセスしているから、DBIか何かのバグ!?



で、さっきようやく原因がわかった。
原因は初歩的なミス…。

DBIではSQL文をまずprepareしてからexecuteするのだが、INSERT文の部分だけprepareが抜けていた。
よって、INSERT文の代わりに前のSELECT文がもう一度実行されていたのだ。

う~ん…、ちゃんと動いているプログラムからコピペして書き換えただけだったのに…。
しかも、INSERT文付近はほとんど書き換えてないのに…。
操作ミスか何かで消しちゃったのかな…。

貴重な時間を無駄にしてしまいました。