Non posso dire nulla sull'esecuzione della query, mi dispiace. Ma potresti prendere in considerazione i trigger per evitare che il caso del "new_balance" diventi negativo. (Perché mi sembra strano fare un inserimento nullo nel caso in cui 'new_balance' sia inferiore a $amount, ma potrebbe comunque funzionare :)).
Vedi documentazione di MySQL 5.0 per i dettagli su come creare un trigger.
Fondamentalmente dovresti mettere il segno di spunta, se NEW.new_balance è negativo in un PRIMA-trigger. In caso affermativo, utilizzeresti un "STOP ACTION", un errore deliberato nell'esecuzione, per interrompere il trigger e la query INSERT. Vedi le idee nella pagina menzionata nei commenti.
Aggiornamento:ho armeggiato un po' (la mia scusa per installare MySQL a casa).
La mia versione ha il problema di scrivere una seconda volta nel DB per ogni valore inserito in moneylog.
Forse sarebbe consigliabile passare a un processo memorizzato. O qualcun altro ha un'idea migliore, non sono molto interessato a DB :)
CREATE DATABASE triggertest;
CONNECT triggertest;
CREATE TABLE transferlog (
account SMALLINT UNSIGNED NOT NULL ,
amount INT NOT NULL,
new_balance INT NOT NULL
) ENGINE=INNODB;
CREATE TABLE stopaction (
entry CHAR(20) NOT NULL,
dummy SMALLINT,
UNIQUE(`entry`)
);
INSERT INTO stopaction (`entry`) VALUES ('stop');
DELIMITER #
CREATE TRIGGER nonneg_insert BEFORE INSERT ON transferlog
FOR EACH ROW BEGIN
INSERT INTO stopaction (`entry`)
SELECT CASE WHEN NEW.new_balance<0 THEN 'stop'
ELSE 'none' END;
DELETE FROM stopaction WHERE entry!='stop';
END;
#
CREATE TRIGGER nonneg_update BEFORE UPDATE ON transferlog
FOR EACH ROW BEGIN
INSERT INTO stopaction (`entry`)
SELECT CASE WHEN NEW.new_balance<0 THEN 'stop'
ELSE 'none' END;
DELETE FROM stopaction WHERE entry!='stop';
END;
#
DELIMITER ;
INSERT INTO transferlog (`account`, `amount`, `new_balance`)
VALUES (1, 1000, 1000);
INSERT INTO transferlog (`account`, `amount`, `new_balance`)
VALUES (1, -1000, 0);
INSERT INTO transferlog (`account`, `amount`, `new_balance`)
VALUES (1, -1000, -1000);
INSERT INTO transferlog (`account`, `amount`, `new_balance`)
VALUES (1, 10, 20);
SELECT version();
DROP DATABASE triggertest;
Forse ti si addice, il mio output per le linee INSERT è:
mysql> INSERT INTO transferlog (`account`, `amount`, `new_balance`) VALUES (1, 1000, 1000);
Query OK, 1 row affected (0.03 sec)
mysql> INSERT INTO transferlog (`account`, `amount`, `new_balance`) VALUES (1, -1000, 0);
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO transferlog (`account`, `amount`, `new_balance`) VALUES (1, -1000, -1000);
ERROR 1062 (23000): Duplicate entry 'stop' for key 1
mysql> INSERT INTO transferlog (`account`, `amount`, `new_balance`) VALUES (1, 10, 20);
Query OK, 1 row affected (0.02 sec)
mysql> SELECT version();
+---------------------+
| version() |
+---------------------+
| 5.0.67-community-nt |
+---------------------+
1 row in set (0.00 sec)