# Doppelte Einträge vermeiden und wechselnde Optionen



## WebMarco (18. Oktober 2012)

Guten Tag liebe Helfergemeinde,

nach langem probieren und mit Unterstützung des Forums ist es mir gelungen, die Terminfunktion für unseren Tauchverein so umzusetzen, dass nur aktuelle, noch nicht verstrichene Termine angezeigt werden. Außerdem konnte ich bereits umsetzen, dass Zu- bzw. Absagen von registrierten Usern (mit Übermittlung derer User_ID) für einen jeweiligen  Termin getätigt werden können.




Leider ist es nun so, dass bei jedem Klicken des Zu- oder Absagebuttons ein Eintrag in die MySQL-Datenbank vorgenommen wird. Also kann ein User auch zwanzigfach für einen Termin zu- und absagen.




Ich habe nun bereits mehrere "INSERT DISTINCT"-Varianten durchprobiert. Auch habe ich versucht, durch UNIQUE-setzen verschiedener Spalten in der Tabelle, Doppelteintragungen zu vermeiden. Doch selbst, wenn dies soweit geklappt hätte, dass ein User nur einmal je Termin eine Zu- bzw. Absage tätigen kann, wäre die Funktion, seine Meinung zu ändern nicht umgesetzt. Ich beabsichtige, den bereits geklickten Button verschwinden zu lassen. Wird dann jedoch der jeweils andere Button geklickt, so soll sich der Eintrag in der DB ändern und der jeweils andere Button wieder auftauchen. Sprich: bevor überhaupt eine Angabe zu einem Termin gemacht wurde, sollen beide Buttons dastehen, nach klicken eines Buttuns nur noch der jeweils andere, um seine Auswahl jederzeit zu ändern.


```
function send(action,id) {

...

else if(action==6) {
  if (confirm("Zusagen?"))
  document.form.action.value = "teilnahme";
    else
      return;
}

else if(action==7) {
  if (confirm("Absagen?"))
  document.form.action.value = "absage";
    else
      return;
}

  document.form.id.value = id;
  document.form.submit();
}


  echo ' <form name="form" action="" method="post"> ';
  echo ' <input name="action" type="hidden" /> ';
  echo ' <input name="id" type="hidden" /> ';

/* Aktionen */
if(isset($_POST["action"])) {

/* Zusage */
if($_POST["action"]=="teilnahme") {
  $select = "INSERT INTO termine_teilnehmer (benutzer_id, termine_id, teilnahme) VALUES ('" . $_SESSION[user_id] . "', '" . $_POST["id"] . "', '1')";
  mysql_query($select);
  if (mysql_affected_rows () > 0) {
  echo ' Die Zusage von ' . $_SESSION["user_vorname"] . ' ' . $_SESSION["user_nachname"] . ' wurde erfolgreich eingetragen.<br />Jetzt <a href="http://'. $_SERVER['SERVER_NAME']. '/termine.html">aktualisieren</a> um aktuelle Eintragung anzuzeigen ';
  }
  else {
  echo ' Es ist ein Fehler aufgetreten. ';
  }
}

/* Absage */
elseif($_POST["action"]=="absage") {
  $select = "INSERT INTO termine_teilnehmer (benutzer_id, termine_id, teilnahme) VALUES ('" . $_SESSION[user_id] . "', '" . $_POST["id"] . "', '0')";
  mysql_query($select);
  if (mysql_affected_rows () > 0) {
  echo ' Die Absage von ' . $_SESSION["user_vorname"] . ' ' . $_SESSION["user_nachname"] . ' wurde erfolgreich eingetragen.<br />Jetzt <a href="http://'. $_SERVER['SERVER_NAME']. '/termine.html">aktualisieren</a> um aktuelle Eintragung anzuzeigen. ';
  }
  else {
  echo ' Es ist ein Fehler aufgetreten. ';
  }
}

}

// Termine
if (is_array($termine))
{
  foreach ($termine as $eintrag)
  {
  // Ausgabe der einzelnen Termindaten
    if (isset ($_SESSION['user_id']))
    {
      echo ' Teilnehmer<br /> ';
      if ($termine_teilnahme[$eintrag['id']] != NULL)
      {
        foreach ($termine_teilnahme[$eintrag['id']] as $teilnahme)
        {
            echo ' ' . $teilnahme['vorname'] . ' ' . $teilnahme['nachname'] . ' ';
        }
      }
      else
      {
        echo ' Es gibt noch keine Teilnehmer. ';
      }
      echo ' Absagen<br /> ';
      if ($termine_absage[$eintrag['id']] != NULL)
      {
        foreach ($termine_absage[$eintrag['id']] as $absage)
        {
            echo ' ' . $absage['vorname'] . ' ' . $absage['nachname'] . ' ';
        }
      }
      else
      {
        echo ' Es gibt noch keine Absagen. ';
      }
<input type="submit" value="zusagen" onclick="javascript:send(6,' . $eintrag['id'] . ');" />
<input type="submit" value="absagen" onclick="javascript:send(7,' . $eintrag['id'] . ');" />
    }
  }
}
  else
  {
    echo ' Keine Termine verfügbar. ';
  }

  echo ' </form> ';
```

Bei der Prüfung, ob ein Eintrag bereits vorhanden ist, sind ja benutzer_id, termine_id und teilnahme der Tabelle termine_teilnehmer  in Zusammenhang zu bringen. Also einfach einen INDEX über eine Spalte zu legen, wäre ja quatsch. Denn die Spalte teilnahme etwa kann ja nur 1 = Teilnahme und 0 = Absage beinhalten. Genauso können die termine_id und benutzer_id auch doppelte Einträge beinhalten. Wenn der User mit der ID 5 zu vier verschiedenen Terminen seine Teilnahme bekundet, taucht ja jeweils die ID 5 in der Spalte benutzer_id auf.

Es soll also folgendes verindert werden:

[termine_teilnehmer]
id | benutzer_id | termine_id | teilnahme
---------------------------------------------------
1 | 5 | 2 | 1
2 | 5 | 2 | 0

und eben:

1 | 5 | 2 | 1
2 | 5 | 2 | 1

Für Denkanstöße und LösungsANSÄTZE bin ich wirklich sehr dankbar. Leider reichen meine Programmierkenntnisse noch nicht aus, um auf teilweise die "einfachsten" Lösungen zu stoßen.


----------



## Yaslaw (18. Oktober 2012)

- UNIQUE KEY setzen auf benutzer_id & termine_id

- INSERT durch INSERT...ON DUPLICATE KEY UPDATE ersetzen

Sumit wird ein neuer Eintrag erstellt wenn noch keiner da ist, ansonsten wird der bestehende abngepasst...


----------



## WebMarco (26. Oktober 2012)

Vielen Dank,

die Lösung war ja einfacher als ich dachte. Mir fehlt noch ein wenig das Verständnis für die Schlüsselvergabe bei MySQL. Aber ich werde mich weiterhin damit beschäftigen.

Hier die Lösung:


```
if($_POST["action"]=="teilnahme") {
  $select = "INSERT INTO termine_teilnehmer (benutzer_id, termine_id, teilnahme) VALUES ('" . $_SESSION[user_id] . "', '" . $_POST["id"] . "', '1') ON DUPLICATE KEY UPDATE teilnahme = '1'";
```

Bei der Absage entsprechend den Wert auf '0'


----------



## Yaslaw (26. Oktober 2012)

Noch ein Tipp am Rande. SQL auch in PHP formatieren....

a) den SQL-Teil in PHP formatieren: Heredoc-Syntax
b) Die Complex (Curly) Syntax anwenden um die Strings zusammenzusetzen. Das reduziert das Chaos mit öffnenden und schliessenden Anführungszeichen und den Verbindungs-Punkten


```
if($_POST["action"]=="teilnahme") { 
	$sql = <<<SQL
INSERT INTO 
	termine_teilnehmer
	 (
		benutzer_id, 
		termine_id, 
		teilnahme
	) 
VALUES
	 (
		{$_SESSION['user_id']}, 
		{$_POST['id']}, 
		1
	) 
ON DUPLICATE KEY UPDATE 
	teilnahme = 1
SQL;
	$result = mysql_query($sql)
}
```

Nachtrag:
Die IDs sind Zahlen. Also darf man sie in SQL auch als Zahlen behandeln und ohne ' schrieben


----------

