Signaler

Column ...cannot be null [Résolu]

Posez votre question mc69360 19Messages postés vendredi 4 août 2017Date d'inscription 9 août 2017 Dernière intervention - Dernière réponse le 6 août 2017 à 22:45 par mc69360
Bonjour,
nouveau sur comment ça marche et avec le php
je galère depuis quelques temps avec une portion de code:
<?php
//Rien de reçu => on bosse pas
if (!empty($_POST)) {
//Je mets tout dans un T/C
try {
//TOUJOURS ACTIVER LES EXCEPTIONS
$bdd = new PDO('mysql:host=localhost;dbname=crealis;charset=utf8', 'root', '',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$toutes_donnees = $bdd->query('SELECT * FROM stock_antigel')->fetchAll();
$requeteUpdate = "UPDATE stock_antigel SET mesure_observee = :mesure_observee,stock_reel = :stock_reel WHERE id = :id";
$stmt = $bdd->prepare($requeteUpdate);
$stmt->bindParam(':mesure_observee', $mesure, PDO::PARAM_STR);
$stmt->bindParam(':stock_reel', $stock_reel, PDO::PARAM_INT);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
foreach($toutes_donnees as $donnees){
$id = $donnees['id'];
$mesure = $_POST["mesure_observee$id"];
$hauteur =$_POST["mesure_observee"];
if($donnees['facteur_conversion_mesureareel'] != 0){
$stock_reel = $mesure * $donnees['facteur_conversion_mesureareel'];}
else{
$toutes_tables = $bdd->prepare('SELECT volume FROM table_stockage WHERE hauteur = :hauteur');
$toutes_tables->bindParam(':hauteur',$donnees['mesure_observee'], PDO::PARAM_STR);
$toutes_tables->execute();
foreach($toutes_tables as $table){
$stock_reel = $table['volume'];
}}

if (!$stmt->execute()) {
throw new Exception('ERREUR UPDATE (ID '.$_POST['id'].')');
}
} //fin foreach
header('Location: index.php');
}catch (PDOException $pdoE) {
echo 'Exception PDO: '.$pdoE->getMessage();
} catch (Exception $e) {
echo 'Exception Autre: '.$e->getMessage();
}
}


me retourne:
Exception PDO: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'stock_reel' cannot be null

or $table['volume'] n'est pas censé être null
Merci

Utile
+0
plus moins
Bonjour

Tu es récupères où te variables post ?
Que vaut $stock_reel ??
Car bon... le message d'erreur est pourtant clair et facile à comprendre. ...

Donnez votre avis
Utile
+0
plus moins
Salut, oui le message est clair
je récupère ici:
<?php
include 'sqlconnect.php';
// On récupère tout le contenu de la table stock_antigel

$toutes_donnees = $bdd->query('SELECT * FROM stock_antigel')->fetchAll();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="stock_antigel.css" />
<title>Relevé de niveaux Stock Antigel</title>
</head>
<body>
<?php
include 'header.html';
include 'menu.html';
?>
<?php if(isset($toutes_donnees)): ?>
<form action="stock_antigel_update.php" method="post">
<p>
<?php foreach($toutes_donnees as $donnees): ?>
<input type="hidden" name="id<?php echo $donnees['id'];?>" value="<?php echo $donnees['id'];?>"/>
<label for="niveau_matiere_premiere"><?php echo $donnees['matiere_premiere'] . ' :'; ?></label> <input type="number" step="0.01" name="mesure_observee<?php echo $donnees['id']; ?>" id="mesure_observee" value="<?php echo $donnees['mesure_observee']; ?>"/><br /><br />
<?php endforeach; ?>

<input type="submit" value="Envoyer" />
</p>

</form>
<?php else: ?>
<p>Une erreur a eu lieu avec la base de donnée. Nous vous présentons nos excuses pour la gêne occasionnée.</p>
<?php endif; ?>
</body>
</html>
jordane45 18470Messages postés mercredi 22 octobre 2003Date d'inscription ModérateurStatut 21 octobre 2017 Dernière intervention - 5 août 2017 à 13:43
Ce n'est pas le même fichier... donc non.. ce n ai pas là que tu "récupères" le contenu de tes variables POST...
Répondre
jordane45 18470Messages postés mercredi 22 octobre 2003Date d'inscription ModérateurStatut 21 octobre 2017 Dernière intervention - 5 août 2017 à 13:44
Quand je parle de récupérer. . Je veux dire lire la valeur de $_POST et mettre dans une variable pour l'utiliser ensuite dans tes requetes insert / update
Répondre
jordane45 18470Messages postés mercredi 22 octobre 2003Date d'inscription ModérateurStatut 21 octobre 2017 Dernière intervention - 5 août 2017 à 13:45
Regarde ici comment faire la recup proprement
http://www.commentcamarche.net/faq/1391-php-notice-undefined-index
Répondre
Donnez votre avis
Utile
+0
plus moins
bonjour,
je trouve cette partie de code bizarre:
foreach($toutes_tables as $table)
{
                $stock_reel = $table['volume'];
}

que veux-tu y faire exactement?

par ailleurs, je vois deux instructions qui assignent une valeur à $stock_reel. il est très possible, vu la logique de ton code, que tu n'exécutes aucune des deux, et donc que $stock_reel soit vide.

je suggère, aussi, de déplacer hors du foreach le prepare et bindparam de $toutes_tables.
mc69360 19Messages postés vendredi 4 août 2017Date d'inscription 9 août 2017 Dernière intervention - 5 août 2017 à 20:07
Oui, je crois bien que c'est un problème de logique et de compréhension
En fait dans un formulaire je récupère une hauteur
$mesure = $_POST["mesure_observee$id"];
avec cette mesure(qui a pour champ hauteur), je voudrais récupérer une valeur(volume) dans une autre table (table_stockage)
Répondre
yg_be 3589Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 21 octobre 2017 Dernière intervention - 5 août 2017 à 20:30
tu n'as pas tenu compte de plusieurs suggestions et tu n'as pas répondu à plusieurs questions.
suggestions et questions supplémentaires:
- cela n'a pas de sens de mettre les instructions suivantes dans un foreach:
$mesure = $_POST["mesure_observee$id"];
$hauteur =$_POST["mesure_observee"];

- ajoute
print_r($_POST);
, et partage le résultat.
- que veux-tu obtenir avec
$_POST["mesure_observee$id"]
? peut-être
$_POST["mesure_observee".$id]
?
- ajoute des instructions "echo" pour vérifier que ton programme se comporte comme tu veux.
- partage le code html source de la page affichée
Répondre
mc69360 19Messages postés vendredi 4 août 2017Date d'inscription 9 août 2017 Dernière intervention - 5 août 2017 à 21:27
Oups, j'ai répondu mais le message apparait au dessus ...
Répondre
Donnez votre avis
Utile
+0
plus moins
le
fetchAll 
est-il optionnel après un execute?
$toutes_tables->execute();
foreach($toutes_tables as $table)
Donnez votre avis
Utile
+0
plus moins
mon fichier index:

<?php
include 'header.html';
include 'sqlconnect.php';
?>
<?php

// On récupère tout le contenu de la table stock_antigel

$toutes_donnees = $bdd->query('SELECT * FROM stock_antigel ORDER BY stock_antigel.id ASC')->fetchAll();

?>
<html>
<head>

<meta charset="utf-8" />
<link rel="stylesheet" href="stock_antigel.css" />
<title>Stock Antigel</title>

</head>

<body>
<h1>SUIVI STOCK ANTIGEL</h1>

<?php
include 'menu.html';
?>
<br>
<br>
<br>
<center>
<table>


<thead> <!-- En-tête du tableau -->
<tr class="couleur_tr">
<th>Matière première</th>
<th>Code Produit</th>
<th>Emplacement</th>
<th>Mesure observée</th>
<th>Stock réel</th>
<th>Niveau déclenchement appro</th>
<th>Niveau alarme</th>
</tr>
</thead>

<tfoot> <!-- Pied de tableau -->
<tr class="couleur_tr">
<th>Matière première</th>
<th>Code Produit</th>
<th>Emplacement</th>
<th>Mesure observée</th>
<th>Stock réel</th>
<th>Niveau déclenchement appro</th>
<th>Niveau alarme</th>
</tr>
</tfoot>
<?php foreach($toutes_donnees as $donnees): ?>
<tbody> <!-- Corps du tableau -->
<tr>
<td><?php echo $donnees['matiere_premiere'];?></td>
<td><?php echo $donnees['code_produit'];?></td>
<td><?php echo $donnees['emplacement'];?></td>
<td><?php echo $donnees['mesure_observee'];?></td>
<td><?php echo $donnees['stock_reel'];?></td>
<td><?php echo $donnees['niveau_appro'];?></td>
<td><?php echo $donnees['niveau_alarme'];?></td>

</tr>
<?php endforeach; ?>

</tbody>
</table>
</center>
</body>
</html>


mon formulaire:

<?php
include 'sqlconnect.php';
// On récupère tout le contenu de la table stock_antigel

$toutes_donnees = $bdd->query('SELECT * FROM stock_antigel')->fetchAll();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="stock_antigel.css" />
<title>Relevé de niveaux Stock Antigel</title>
</head>
<body>
<?php
include 'header.html';
include 'menu.html';
?>
<?php if(isset($toutes_donnees)): ?>
<form action="stock_antigel_update.php" method="post">
<p>
<?php foreach($toutes_donnees as $donnees): ?>
<input type="hidden" name="id<?php echo $donnees['id'];?>" value="<?php echo $donnees['id'];?>"/>
<label for="niveau_matiere_premiere"><?php echo $donnees['matiere_premiere'] . ' :'; ?></label> <input type="number" step="0.01" name="mesure_observee<?php echo $donnees['id']; ?>" id="mesure_observee" value="<?php echo $donnees['mesure_observee']; ?>"/><br /><br />
<?php endforeach; ?>

<input type="submit" value="Envoyer" />
</p>

</form>
<?php else: ?>
<p>Une erreur a eu lieu avec la base de donnée. Nous vous présentons nos excuses pour la gêne occasionnée.</p>
<?php endif; ?>
</body>
</html>


mon fichier de traitement avec mes derniers bricolages qui ne donnent rien de mieux par rapport à mon premier message...

<?php
//Rien de reçu => on bosse pas
if (!empty($_POST)) {
//Je mets tout dans un T/C
try {
//TOUJOURS ACTIVER LES EXCEPTIONS
$bdd = new PDO('mysql:host=localhost;dbname=crealis;charset=utf8', 'root', 'lionel0769',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$toutes_donnees = $bdd->query('SELECT * FROM stock_antigel')->fetchAll();
$requeteUpdate = "UPDATE stock_antigel SET mesure_observee = :mesure_observee,stock_reel = :stock_reel WHERE id = :id";
$stmt = $bdd->prepare($requeteUpdate);
$stmt->bindParam(':mesure_observee', $mesure, PDO::PARAM_STR);
$stmt->bindParam(':stock_reel', $stock_reel, PDO::PARAM_STR);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
foreach($toutes_donnees as $donnees){
$id = $donnees['id'];
$mesure = $_POST["mesure_observee$id"];
if($donnees['facteur_conversion_mesureareel'] != 0){
$stock_reel = $mesure * $donnees['facteur_conversion_mesureareel'];}
else{
$toutes_tables = $bdd->prepare("SELECT volume FROM table_stockage WHERE hauteur = :hauteur");
$toutes_tables->bindParam(':hauteur',$mesure, PDO::PARAM_STR);
$toutes_tables->execute();
$mesure = $_POST["mesure_observee$id"];
foreach($toutes_tables as $table){
$stock_reel = $table->fetch(PDO::FETCH_ASSOC);
}}

if (!$stmt->execute()) {
throw new Exception('ERREUR UPDATE (ID '.$_POST['id'].')');
}
} //fin foreach
header('Location: index.php');
}catch (PDOException $pdoE) {
echo 'Exception PDO: '.$pdoE->getMessage();
} catch (Exception $e) {
echo 'Exception Autre: '.$e->getMessage();
}
}
?>


$_POST["mesure_observee$id"] répond bien à mes attentes, il crée une boucle

http://img-19.ccm2.net/TomADgAKapBkLAIQ9xycYENnz5I=/0ea258a1368945dc8ade9c9bccf25bea/ccm-ugc/snapshot9.png
yg_be 3589Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 21 octobre 2017 Dernière intervention - 5 août 2017 à 21:44
ce serait beaucoup plus clair si tu choisissais de partager ton code comme du code "php", ainsi:
<?php
    //Rien de reçu => on bosse pas
    if (!empty($_POST)) {
        //Je mets tout dans un T/C
        try {
            //TOUJOURS ACTIVER LES EXCEPTIONS
            $bdd = new PDO('mysql:host=localhost;dbname=crealis;charset=utf8', 'root', 'lionel0769',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
            $toutes_donnees = $bdd->query('SELECT * FROM stock_antigel')->fetchAll();
            $requeteUpdate = "UPDATE stock_antigel SET mesure_observee = :mesure_observee,stock_reel = :stock_reel WHERE id = :id";
            $stmt = $bdd->prepare($requeteUpdate);
            $stmt->bindParam(':mesure_observee', $mesure, PDO::PARAM_STR);
            $stmt->bindParam(':stock_reel', $stock_reel, PDO::PARAM_STR);
            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
            foreach($toutes_donnees as $donnees){
                $id = $donnees['id'];
                $mesure = $_POST["mesure_observee$id"];
               if($donnees['facteur_conversion_mesureareel'] != 0){
                $stock_reel = $mesure * $donnees['facteur_conversion_mesureareel'];}
                else{
                $toutes_tables = $bdd->prepare("SELECT volume FROM table_stockage WHERE hauteur = :hauteur");
                $toutes_tables->bindParam(':hauteur',$mesure, PDO::PARAM_STR);
                $toutes_tables->execute();
                $mesure = $_POST["mesure_observee$id"];
                foreach($toutes_tables as $table){
                $stock_reel = $table->fetch(PDO::FETCH_ASSOC);
               }}
 
                if (!$stmt->execute()) {
                    throw new Exception('ERREUR UPDATE (ID '.$_POST['id'].')');
                }
            } //fin foreach
            header('Location: index.php');
         }catch (PDOException $pdoE) {
            echo 'Exception PDO: '.$pdoE->getMessage();
        } catch (Exception $e) {
            echo 'Exception Autre: '.$e->getMessage();
        }
    }
?>

je suggère de déplacer hors du foreach le prepare et bindparam de $toutes_tables (les lignes 25 à 28).
la ligne 30 est inutile, tu l'as déjà fait en 20.
ne devrais-tu pas tester que la requête en ligne 29 te renvoie des données, et faire un traitement particulier sinon?
je pense que tu as deux soucis avec les lignes 31 à 33:
- tu n'utilises que la dernière valeur de $stock_reel, pourquoi?
- j'utilisation du fetch est bizarre; suggestion:
$toutes_tables->execute();
$resultat_toutes_tables=$toutes_tables->fetchAll();
foreach($resultat_toutes_tables as $table){
                $stock_reel = $table['volume'];

Tu pourrais aussi, quand tu as une exception, ajouter des print_r de $stock_reel, de $resultat_toutes_tables, de $table, de $toutes_donnees, de $donnees et de $_POST: cela t'aiderait beaucoup à comprendre ce qui se passe.
Répondre
mc69360 19Messages postés vendredi 4 août 2017Date d'inscription 9 août 2017 Dernière intervention - 5 août 2017 à 23:14
<?php
    //Rien de reçu => on bosse pas
    if (!empty($_POST)) {
        //Je mets tout dans un T/C
        try {
            //TOUJOURS ACTIVER LES EXCEPTIONS
            $bdd = new PDO('mysql:host=localhost;dbname=crealis;charset=utf8', 'root', 'lionel0769',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
            //J'ai déplacé le prepare et le bindparam
            $toutes_tables = $bdd->prepare("SELECT volume FROM table_stockage WHERE hauteur = :hauteur");
            $toutes_tables->bindParam(':hauteur',$mesure, PDO::PARAM_STR);
            $toutes_donnees = $bdd->query('SELECT * FROM stock_antigel')->fetchAll();
            $requeteUpdate = "UPDATE stock_antigel SET mesure_observee = :mesure_observee,stock_reel = :stock_reel WHERE id = :id";
            $stmt = $bdd->prepare($requeteUpdate);
            $stmt->bindParam(':mesure_observee', $mesure, PDO::PARAM_STR);
            $stmt->bindParam(':stock_reel', $stock_reel, PDO::PARAM_STR);
            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
            foreach($toutes_donnees as $donnees){
                $id = $donnees['id'];
                $mesure = $_POST["mesure_observee$id"];
               if($donnees['facteur_conversion_mesureareel'] != 0){
                $stock_reel = $mesure * $donnees['facteur_conversion_mesureareel'];}
                else{
                $toutes_tables->execute();
                // J'ai supprimé le deuxième $mesure
                //je change le fetch comme suggéré
                $resultat_toutes_tables=$toutes_tables->fetchAll();
                foreach($resultat_toutes_tables as $table){
                $stock_reel = $table['volume'];
               }}
                //je test si $toutes_tables est exécuté sinon message d'erreur                
                if (!$stmt->execute() or !$toutes_tables->execute()) {
                    throw new Exception('ERREUR UPDATE (ID '.$_POST['id'].')');
                }
            } //fin foreach
            header('Location: index.php');
         }catch (PDOException $pdoE) {
            echo 'Exception PDO: '.$pdoE->getMessage();
        } catch (Exception $e) {
            echo 'Exception Autre: '.$e->getMessage();
        }
    }
?>


Par contre je n'ai pas compris ce que tu dis comme quoi je n' utilise que la dernière valeur de $stock_reel
les print_r ils sont à mettre dans mon fichier html?
Répondre
yg_be 3589Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 21 octobre 2017 Dernière intervention - 5 août 2017 à 23:28
ton test or !$toutes_tables->execute() n'est pas correct. que doit-il se passer si la hauteur n'est pas présente dans la table table_stockage?
suggestion, avant la ligne 22, tu ajoutes
$stock_reel = NULL;
, et avant la ligne 38, tu ajoutes:
if (is_null($stock_reel)) {
                    throw new Exception('Pas trouvé $stock_reel (ID '.$id.')');
}



comprends-tu ce que font les instructions suivantes? à quoi servent-elles? pourquoi changer plusieurs fois la valeur de $stock_reel, sans l'utiliser entre chaque changement? peux-tu avoir plusieurs volumes pour la même hauteur dans la table table_stockage?
foreach($resultat_toutes_tables as $table){
                $stock_reel = $table['volume'];
}


les print_r sont à mettre avec les echo en cas d'exception. regarde la documentation php. fais aussi print_r de $id. ou bien fais simplement
print_r(get_defined_vars());
Répondre
Donnez votre avis
Utile
+0
plus moins
Salut et merci de ta patience...
Donc j'ai commencé à faire un print_r de toutes tables qui me renvoie rien
j'ai ensuite comme tu m'as dit ajouté le stock_reel = NULL; et la condition
qui me répond qu'il n'a pas trouvé id27 qui correspond à test


Pour le foreach, je parcours le tableau $resultat et j'affecte la valeur trouvé à $table sauf qu'effectivement je n'ai pas plusieurs volume pour la même hauteur donc je peux le supprimer, c'est bien ça ?
yg_be 3589Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 21 octobre 2017 Dernière intervention - 6 août 2017 à 11:23
fais ainsi:
                foreach($resultat_toutes_tables as $table){
                $stock_reel = $table['volume'];
               }}
               if (is_null($stock_reel)) {
                    throw new Exception('Pas trouvé $stock_reel (ID '.$id.')');
}                //je test si $toutes_tables est exécuté sinon message d'erreur                
                if (!$stmt->execute() ) {

L'erreur "Pas trouvé $stock_reel" se produit parce que la hauteur n'est pas trouvée dans la bdd. Peut-être un problème d'arrondi?
Répondre
mc69360 19Messages postés vendredi 4 août 2017Date d'inscription 9 août 2017 Dernière intervention - 6 août 2017 à 11:39
https://img4.hostingpics.net/pics/368483snapshot9.png

C'est à dire problème d' arrondi?, ma valeur dans la bdd est bien 1.45 qui est bien égale à celle demandée

Est ce que ça pourrait être le type de mon champ hauteur qui est float?
https://img4.hostingpics.net/pics/469226snapshot11.png

Edit: effectivement en passant le type de float à double, ça résout le problème
Répondre
yg_be 3589Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 21 octobre 2017 Dernière intervention - 6 août 2017 à 12:27
peut-être ainsi?
$toutes_tables = $bdd->prepare("SELECT volume FROM table_stockage WHERE ROUND(hauteur , 2) = ROUND(:hauteur , 2) ");
Répondre
mc69360 19Messages postés vendredi 4 août 2017Date d'inscription 9 août 2017 Dernière intervention - 6 août 2017 à 21:30
changer le type dans la bdd n'est pas valable?
Répondre
yg_be 3589Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 21 octobre 2017 Dernière intervention - 6 août 2017 à 22:06
moi je pense plus prudent de faire avec round (éventuellement en mettant 5 ou 6 au lieu de 2). c'est le nombre de chiffres après la virgule pour la comparaison.
Répondre
Donnez votre avis
Utile
+0
plus moins
ok , merci
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !