2009-06-13 6 views
2

En utilisant la commande de mise à jour, je veux changer le type_name pour une entrée spécifique dans la base de données, mais il change le type_name pour toutes les entrées avec le même type_id.Pourquoi ma commande Update met-elle à jour tous les champs ayant le même ID?

J'ai besoin de seulement changer type_name de cette entrée individuelle, et non le type_name qui est associé à toutes les entrées avec le même type_id.

J'ai une requête de mise à jour:

$sql = 'UPDATE photos 
     LEFT JOIN types 
     ON photos.type_id = types.type_id 
     SET photos.photo_title = $_POST['photo_title'], 
      types.type_name = $_POST['type_name'] 
     WHERE photos.photo_id = 3'; 

est ici la forme que je utilise:

<form name="form1" method="post" action=""> 
    <input name="photo_title" type="text" value=""/> 
    <textarea name="type_name"></textarea> 
    <input type="submit" name="update" value="Update entry" /> 
</form> 

Voilà ma structure de base de données:

TABLE Photos

  • photo_id CLÉ PRIMAIRE

  • photo_title

  • type_id FOREIGN KEY

types TABLE

  • type_id PRIMARY KEY

  • nom_type

+3

Alors, comment voulez-vous identifier la « entrée individuelle » de la table des types?Votre SQL indique que toutes les lignes dans les types avec le type_id donné doivent être mises à jour - comment identifiez-vous le seul qui doit être mis à jour, par rapport à ceux qui ne doivent pas l'être? –

+0

Votre code est horrible de plusieurs façons que je peux compter. Utilisez une clé primaire pour les mises à jour. N'INCLUEZ PAS DE VARIABLES POSTALES DANS VOTRE SQL! DÉJÀ! Découvrez ce que signifie l'injection SQL et comment utiliser les paramètres. – SpliFF

+0

ouais je sais spliff. Je l'ai juste fait ici pour le rendre plus facile à comprendre ce que j'essaye de faire. J'utilise en fait une instruction préparée et lie mes variables, mais je ne voulais pas la rendre plus confuse pour les personnes qui ne comprennent pas les instructions préparées. – zeckdude

Répondre

2

Ce qui se passe, c'est que votre jointure génère un mauvais ensemble de données. Vous joignez les photos et les types sur type_id.

Maintenant, ce que vous semblez décrire est que la colonne des types peut contenir plusieurs lignes avec le même type ___id. Qu'est-ce que ça veut dire? Cela signifie que votre jointure produira plusieurs paires de (photos,types) pour chaque photo (spécifiquement, pour chaque photo, la jointure produira n lignes, où n est le nombre de lignes dans les types ayant le même type_id que la photo).

Pour résoudre ce problème, vous devriez jeter un coup d'œil à la conception de votre base de données. Vous semblez vous attendre à une rangée unique de types pour chaque photo. Comment cette relation est-elle exprimée? Cela vous permettra d'obtenir une bonne clause ON pour votre inscription.

MISE À JOUR

Après avoir examiné la structure de la table, il semble que votre base de données exprime les choses un peu différemment. En l'état, vous pouvez avoir plusieurs photos avec le même type (c'est-à-dire que leur type dans le tableau des photos est le même). Ainsi, il est un peu inutile de parler de changer le nom de fichier d'une telle photo.Vous mettez simplement à jour le nom de fichier pour un type particulier, qui se trouve être le type de la photo dont vous avez également mis à jour le nom.

Maintenant, qu'est-ce que vous essayez exactement de réaliser ici?

  • Si vous essayez de nouveau classer une photo en particulier, alors vous voulez plutôt créer une nouvelle entrée dans la table des types et pointez votre photo à ce nouveau record, ou trouver une photo existante avec un nom correspondant et pointez la photo sur cet enregistrement. (Je suppose que vous avez déjà un tel code dans votre logique d'insertion photo.)
  • Si vous essayez de mettre à jour la description du type pour une photo et toutes les autres photos avec ce type, alors ce que vous avez fonctionnera très bien .
+0

Yuliy, j'ai ajouté ma structure de base de données. Cela aide-t-il à clarifier les choses? – zeckdude

+0

Oui, c'est le cas. J'ai ajouté un peu plus à la réponse basée sur cela. – Yuliy

+0

"vous souhaitez plutôt créer une nouvelle entrée dans la table des types et pointer votre photo vers ce nouvel enregistrement" Pouvez-vous me donner des exemples de code sur la façon dont je pourrais y parvenir? Je veux faire une instruction if qui vérifiera si le type_name entré existe déjà dans la colonne type_name et si c'est le cas, alors changez-le en type_id spécifique et si le type_name n'existe pas, insérez un nouvel enregistrement. Savez-vous comment je pourrais programmer cela? – zeckdude

-1
$sql = 'UPDATE photos 
     LEFT JOIN types 
     ON photos.type_id = types.type_id 
     SET photos.photo_title = $_POST['photo_title'], types.type_name = $_POST['type_name'] 
     WHERE photos.photo_id = 3 LIMIT 1'; 

Sur une note de côté, vous accomplirez shoule

$photo_title = escape_function($_POST['photo_title']) 
$type_name = escape_function($_POST['type_name']) 

et envelopper les noms Varialble dans '' dans votre chaîne de requête.

+3

cela va changer juste une rangée, mais pourquoi cette rangée serait-elle la "bonne" automagickally ?! –

0

J'ai besoin pour ne changer que nom_type de l'entrée individuelle, et non le nom_type qui est associé à toutes les entrées avec le même type_id.

Ceci est votre problème fondamental. Il n'y aura jamais qu'un seul enregistrement dans la base de données par type typeid, donc quand vous le modifiez, il le modifie effectivement pour chaque photo qui fait référence à typeid.

Si vous avez besoin de stocker un type_name différent pour chaque photo, créez simplement une colonne dans le tableau photos et stockez-la là.

L'autre façon de le faire est de créer un nouveau record dans le tableau types chaque fois qu'un type_name est modifié - peut-être faire quelques vérifications pour voir si toutes les autres photos sont également à l'aide que typeid (sinon vous pouvez sans risque mettre à jour le enregistrement existant). Mais vous devez implémenter du code qui le fait pour vous-même.

1

Je suis surpris que MySQL le permette, mais il semble que vous mettez à jour le nom dans la table de types. Vous cherchez probablement à mettre à jour le type_id d'une seule ligne dans la table des photos.

Vous pouvez le faire comme ceci:

UPDATE photos 
SET photos.photo_title = $_POST['photo_title'], 
    photos.type_id = (
     select type_id 
     from types 
     where type_name = $_POST['type_name'] 
    ) 
WHERE photos.photo_id = 3 

Ou bien:

UPDATE photos 
LEFT JOIN types ON types.type_id = $_POST['type_name'] 
SET photos.photo_title = $_POST['photo_title'], 
    photos.type_id = types.type_id 
WHERE photos.photo_id = 3 

Avant d'exécuter cette requête, vous pourriez vous assurer existe le nom_type:

REPLACE INTO types (type_name) VALUES ($_POST['type_name']) 
+0

Je pense que vous êtes dans la bonne direction, mais quand j'ai implémenté votre code, il effacé l'id de retour à '0', donc aucun nom de type ne s'affiche maintenant. Des idées? – zeckdude

+0

S'il redéfinit l'ID sur 0, le nouveau nom n'existait probablement pas encore dans la table des types. Avez-vous essayé d'exécuter la requête REPLACE INTO _before_ de la requête UPDATE? La requête REPLACE INTO ajouterait le nouveau type à la table des types. – Andomar

0

Si plus d'une ligne est en cours de mise à jour, alors vous n'utilisez pas une clé unique pour mettre à jour les tables. Il est difficile de comprendre la relation des tables mais il semble que ce soit un rapport 1: M un type peut être ajouté à de nombreuses photos? Si oui, la mise à jour de la table des photos en utilisant le type_id dans la clause WHERE mettra évidemment à jour plus d'une table. Utilisez uniquement les clés primaires qui sont uniques à mettre à jour si vous souhaitez mettre à jour une ligne spécifique.

Vous devez spécifier les relations des tables si vous voulez une solution décente :)

Questions connexes