Encore une question de débutant: Je viens de créer une table qui contient des champs Null: NO. Or je me rend compte que si j'insère un record avec ce champ à null, le système l'accepte quand même et le prend comme chaine vide. En cherchant dans la doc je me rends compte que par défaut le comportement de MySQL est de transformer en valeur "moins pire" mais d'accepter le champ. Je souhaite changer ce comportement par défaut pour une application stricte des règles d'intégrité, et je lis qu'apparement il faut modifier l'option de compilation DONT_USE_DEFAULT_FIELDS, mais je n'ai pas bien compris où je pouvais faire ça et quelle en est la syntaxe. Dans le my.ini? Sur la MySQL console? Ailleurs?
Merci para avance. Pierre
OS: Windows seven Apache: 2.2.11 PHP: 5.3.0 MySQL: 5.1.36
Profitons-en pour parler de NULL (Avant d'arriver à la solution de votre problème)
NULL n'est ni zéro (0), ni une chaine vide ('') et il ne peut être comparé qu'à lui-même : IS NULL ; IS NOT NULL
NULL et le calcul La règle de calcul des Null est simple MAIS trompeuse : tout calcul comprenant un Null a un résultat Null. C'est parfaitement logique : si un paramètre du calcul est inconnu, le résultat du calcul est lui-même inconnu. On retrouve la règle de propagation des Null. L'exception à cette règle est le calcul d'agrégations (les fonctions Count () , Sum () , etc.), qui a ses propres règles : Les fonctions d'agrégation ignorent toujours les Null. S'il n'y a que des Null, le résultat de l'agrégation sera Null... Sauf pour Count O , qui donnera zéro. Afin d'illustrer ces règles, prenons l'exemple d'une table de salariés (nommée par exemple Salaries), avec une colonne contenant leur salaire mensuel et une autre permettant de saisir une prime exceptionnelle : Prenom Salaire Prime Daniel 1500 Null Sarah 2100 Null Laurence 1950 200
SELECT SUM(Salaire + Prime) AS Masse_Salariale FROM Salaries Masse_Salariale 2950 En effet, 1500 + Null est égal à Null, tout comme 2100 + Null. Seule Laurence est donc prise en compte par Sum(Salaire + Prime).
SELECT SUM(Salaire) + SUM(Prime) AS Masse_Salariale FROM Salaries Masse_Salariale 5750 Cette requête est correcte tant qu'au moins un salarié reçoit une prime. Si ce n'est pas le cas, sum (Prime) est Null et donc Sum(Salaire) + Sum(Prime) aussi.
Les Null forment un terrain particulièrement glissant, auquel il faut constamment prêter attention. Dans le cas précité, il aurait été plus judicieux de mettre zéro (0) comme valeur par défaut et non pas NULL
Respect des contraintes d'intégrité et STRICT MODE Historiquement, MySQL est assez indulgent avec les valeurs ne respectant pas les contraintes d'intégrité, et les remplace par des valeurs par défaut, comme si c'étaient des colonnes muettes lors d'une insertion. Ce comportement pouvant mener à des malentendus et affaiblir la cohérence des données, la version 5.0.2 et les suivantes proposent le Strict Mode. Avec ce mode, MySQL ne remplace plus les valeurs interdites par des valeurs par défaut, mais refuse les instructions conduisant à une violation des contraintes d'intégrité.
Donc, tout ce long préambule pour en arriver à forcer le STRICT MODE sur toutes les tables
Dans le fichier wamp\bin\mysql\mysql5.1.xy\my.ini mettre
# Set the SQL mode to strict sql-mode="STRICT_ALL_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Merci beaucoup pour votre réponse. En effet, le null est un terrain glissant mais gérable. Par contre, comme vous le soulignez, j'étais préoccupé par l'indulgence de MySQL qui conduit effectivemet à des malentendus. De fpormation BD formelle je préfère et recommande l'usage de règle strictes. Je vais mettre en place le "Strict mode" de ce pas.
Hehehee, et oui, les règles strictes posent problèmes:
En l'occurrence, je fais un insert tout bête, mais rien ne s'ajoute dans ma table. Surment un problème de null ou pas null mais ce qui m'embête c'est que je ne récupère aucun message d'erreur et que je récupère un "True" à l'exécution de ma requête. C'est normal?
$query = "INSERT INTO contacts VALUES ('','$first','$last','$phone','$mobile','$fax','$email','$web')"; $result=mysql_query($query); mysql_close($link); if ($result="TRUE" ) displaytable($result);