One issue I see is that this conditional test:
IF (identifiant = null)
Will never return TRUE. If you want to test whether a variable is set to the NULL
value, use the IS NULL
operator.
IF (identifiant IS NULL)
I've never used a query as the DEFAULT value for a variable. (That may be valid, I've just never seen it done that way before.)
I'd code it like this:
DECLARE nombreHeure INT;
SELECT COUNT(heure.numero) INTO nombreHeure
FROM heure
WHERE heure.code = NEW.code;
Any place you are assigning the result from a query into a variable, you need to ensure that the query doesn't return more than one row. The query above will return a single row (assuming, that is, it doesn't throw an error), so it's okay.
For a lot of the other queries in your trigger it's not clear (to the casual reader) that these will return only one row.
Another big problem looks like you are local variables have the same name as columns in SQL statements. MySQL isn't going to see that as a reference to a variable, it's going to see it as a reference to a column. (When MySQL encounters a identifier in a SQL statement, it first checks to see if it's a column, only when it can't find a column of that name does it consider that it might be a variable.)
For example:
AND facture.mois = mois
For the reference to mois
on the right side, MySQL first looks for a column named that in one of the tables (from any row source in scope), before it looks at it as a variable. In this case, it's going to find mois
as a column in facture
, so that SQL is basically equivalent to:
AND facture.mois = fracture.mois
which is effectively the same as:
AND facture.mois IS NOT NULL
Basically, you need to ensure that the variable names used in SELECT
statements are distinct from all column names in tables referenced by the query.