web-dev-qa-db-fra.com

Comment stocker des valeurs NULL dans des champs datetime dans MySQL?

J'ai un champ "bill_date" que je veux être vide (NULL) jusqu'à ce qu'il soit facturé, date à laquelle la date sera entrée.

Je vois que MySQL n'aime pas les valeurs NULL dans les champs datetime. L'un de vous a-t-il un moyen simple de gérer cela, ou suis-je obligé d'utiliser la date min comme un "équivalent NULL", puis de vérifier cette date?

Merci.

MODIFIÉ POUR AJOUTER:

Ok, je vois que MySQL acceptera la valeur NULL, mais il ne l'acceptera pas comme une mise à jour de base de données si je mets à jour l'enregistrement en utilisant PHP.

Le nom de la variable est $bill_date mais il ne laissera pas la variable NULL si je mets à jour un enregistrement sans envoyer de valeur à $bill_date - J'obtiens cette erreur:

Database query failed: Incorrect datetime value: '' for column 'bill_date' at row 1

Je suppose que je dois réellement envoyer le mot NULL, ou le laisser complètement hors de la requête de mise à jour, pour éviter cette erreur? Ai-je raison? Merci!!!

40
rhodesjason

MySQL autorise NULL valeurs pour datetime champs. Je viens de le tester:

mysql> create table datetimetest (testcolumn datetime null default null);
Query OK, 0 rows affected (0.10 sec)

mysql> insert into datetimetest (testcolumn) values (null);
Query OK, 1 row affected (0.00 sec)

mysql> select * from datetimetest;
+------------+
| testcolumn |
+------------+
| NULL       | 
+------------+
1 row in set (0.00 sec)

J'utilise cette version:

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.0.45    | 
+-----------+
1 row in set (0.03 sec)

EDIT # 1: Je vois dans votre édition que le message d'erreur que vous obtenez PHP indique que vous passez une chaîne vide (c'est-à-dire ''), pas null. Une chaîne vide est différente de null et n'est pas une valeur datetime valide, c'est pourquoi vous obtenez ce message d'erreur. Vous devez passer le mot clé sql spécial null si c'est ce que vous voulez dire. Aussi, ne mettez pas de guillemets autour du mot null. Voir ma déclaration insert ci-dessus pour un exemple sur la façon d'insérer null.

EDIT # 2: Utilisez-vous PDO? Si c'est le cas, lorsque vous liez votre paramètre null, assurez-vous d'utiliser le [PDO::PARAM_NULL][1] tapez lors de la liaison d'un null. Voir la réponse à cette question stackoverflow sur la façon d'insérer correctement null à l'aide de PDO.

49
Asaph

Ceci est un point sensible.

Une date nulle n'est pas une date nulle. Ils peuvent avoir la même apparence, mais ils ne le sont pas. Dans mysql, une valeur de date nulle est nulle. Une valeur de date zéro est une chaîne vide ('') et '0000-00-00 00:00:00'

A une date nulle "... où mydate = ''" échouera.
À une date vide/nulle "... où ma date est nulle" échouera.

Mais maintenant, allons-y funky. Dans les dates mysql, la date vide/zéro est strictement la même.

par exemple

 sélectionnez si (maDate est null, 'null', myDate) comme mydate de myTable où myDate = ''; 
 sélectionnez si (myDate est null, 'null', myDate) comme mydate de myTable où myDate = '0000-00-00 00:00:00' 

affichera les DEUX: '0000-00-00 00:00:00'. si vous mettez à jour myDate avec '' ou '0000-00-00 00:00:00', les deux sélections fonctionneront toujours de la même manière.

En php, le type de date null mysql sera respecté avec le connecteur mysql standard, et sera de vrais nulls ($ var === null, is_null ($ var)). Les dates vides seront toujours représentées comme '0000-00-00 00:00:00'.

Je conseille fortement de n'utiliser que des dates nulles, OR uniquement des dates vides si vous le pouvez. (Certains systèmes utilisent des dates nulles "virales" qui sont des dates grégoriennes valides, comme 1970-01-01 (linux ) ou 0001-01-01 (Oracle).

les dates vides sont plus faciles dans php/mysql. Vous n'avez pas le "où le champ est nul" à gérer. Cependant, vous devez transformer "manuellement" la date '0000-00-00 00:00:00' en '' pour afficher les champs vides. (pour stocker ou rechercher, vous n'avez pas de cas particulier à gérer pour les dates nulles, ce qui est bien).

Les dates nulles nécessitent de meilleurs soins. vous devez être prudent lorsque vous insérez ou mettez à jour pour NE PAS ajouter de guillemets autour de null, sinon une date zéro sera insérée au lieu de null, ce qui provoque des ravages de vos données standard. Dans les formulaires de recherche, vous devrez gérer des cas tels que "et ma date n'est pas nulle", etc.

Les dates nulles sont généralement plus de travail. mais ils sont BEAUCOUP BEAUCOUP plus rapides que zéro date pour les requêtes.

21
roselan

J'ai eu ce problème sur Windows.

Voici la solution:

Pour passer '' pour NULL, vous devez désactiver STRICT_MODE (qui est activé par défaut sur les installations Windows)

BTW C'est drôle de passer '' pour NULL. Je ne sais pas pourquoi ils ont laissé ce genre de comportement.

7
abzarak

Cela dépend de la façon dont vous déclarez votre table. NULL ne serait pas autorisé dans:

create table MyTable (col1 datetime NOT NULL);

Mais il serait permis:

create table MyTable (col1 datetime NULL);

La seconde est la valeur par défaut, donc quelqu'un doit avoir activement décidé que la colonne ne devrait pas être nullable.

3
Andomar

Je viens de découvrir que MySQL prendra null à condition que la valeur par défaut pour le champ soit null et j'écris des instructions if spécifiques et je laisse les guillemets. Cela fonctionne également pour la mise à jour.

if(empty($odate) AND empty($ddate))
{
  $query2="UPDATE items SET odate=null, ddate=null, istatus='$istatus' WHERE id='$id' ";
};
2
postmarkis

Pour ce que ça vaut: je rencontrais un problème similaire en essayant de mettre à jour une table MySQL via Perl. La mise à jour échouait lorsqu'une valeur de chaîne vide (traduite d'une valeur nulle à partir d'une lecture depuis une autre plate-forme) était transmise à la colonne date ('dtcol' dans l'exemple de code ci-dessous). J'ai finalement réussi à obtenir les données mises à jour en utilisant une instruction IF intégrée à ma déclaration de mise à jour:

    ...
    my $stmnt='update tbl set colA=?,dtcol=if(?="",null,?) where colC=?';
    my $status=$dbh->do($stmt,undef,$iref[1],$iref[2],$iref[2],$ref[0]);
    ...
2
Joe M

Je viens de tester dans MySQL v5.0.6 et la colonne datetime a accepté null sans problème.

2
Rob

En ce qui concerne spécifiquement l'erreur que vous obtenez, vous ne pouvez pas faire quelque chose comme ça dans PHP pour un champ nullable dans MySQL:

$sql = 'INSERT INTO table (col1, col2) VALUES(' . $col1 . ', ' . null . ')';

Parce que null dans PHP équivaudra à une chaîne vide qui est pas identique à une valeur NULL dans MysQL. Au lieu de cela, vous voulez faire ceci:

$sql = 'INSERT INTO table (col1, col2) VALUES(' . $col1 . ', ' . (is_null($col2) ? 'NULL' : $col2). ')';

Bien sûr, vous n'avez pas à utiliser is_null mais je pense que cela démontre un peu mieux le point. Probablement plus sûr d'utiliser empty () ou quelque chose comme ça. Et si $ col2 se trouve être une chaîne que vous mettriez entre guillemets dans la requête, n'oubliez pas pas pour inclure ceux autour de la chaîne 'NULL', sinon cela ne fonctionnera pas.

J'espère que ça t'as aidé!

1
Lukey