SQL - IF EXISTIERT UPDATE ELSE INSERT INTO

77

Was ich versuche, sind INSERTAbonnenten in meiner Datenbank, aber IF EXISTSes sollte UPDATEdie Zeile ELSE INSERT INTOeine neue Zeile sein.

Ofcourse ich auf die Datenbank zuerst und verbinden GETdas $name, $emailund $birthdayaus dem URL - String.

$con=mysqli_connect("localhost","---","---","---");
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

$name=$_GET['name']; 
$email=$_GET['email'];
$birthday=$_GET['birthday'];

Dies funktioniert, fügt jedoch nur die neue Zeile hinzu.

mysqli_query($con,"INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES ('$name', '$email', '$birthday')");

mysqli_close($con);

Folgendes habe ich versucht:

mysqli_query($con,"INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES '$name', '$email', '$birthday'
ON DUPLICATE KEY UPDATE subs_name = VALUES($name), subs_birthday = VALUES($birthday)");
mysqli_close($con);

und

mysqli_query($con,"IF EXISTS (SELECT * FROM subs WHERE subs_email='$email')
    UPDATE subs SET subs_name='$name', subs_birthday='$birthday' WHERE subs_email='$email'
ELSE
    INSERT INTO subs (subs_name, subs_email, subs_birthday) VALUES ('$name', '$email', '$birthday')");
mysqli_close($con);

und

mysqli_query($con,"IF NOT EXISTS(SELECT * FROM subs WHERE subs_email='$email')
Begin
INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES ('$name', '$email', '$birthday')
End");
mysqli_close($con);

Aber keiner von ihnen funktioniert, was mache ich falsch?

Jede Hilfe wird sehr geschätzt!

Laurence Cooper
quelle
2
Haben Sie eine eindeutige Einschränkung für Ihren Tisch?
John Woo

Antworten:

196
  1. Erstellen Sie eine UNIQUEEinschränkung für Ihre subs_emailSpalte, falls noch keine vorhanden ist:

    ALTER TABLE subs ADD UNIQUE (subs_email)
    
  2. Verwendung INSERT ... ON DUPLICATE KEY UPDATE:

    INSERT INTO subs
      (subs_name, subs_email, subs_birthday)
    VALUES
      (?, ?, ?)
    ON DUPLICATE KEY UPDATE
      subs_name     = VALUES(subs_name),
      subs_birthday = VALUES(subs_birthday)
    

Sie können die Funktion VALUES (col_name) in der UPDATE-Klausel verwenden, um auf Spaltenwerte aus dem INSERT-Teil von INSERT ... ON DUPLICATE KEY UPDATE - dev.mysql.com zu verweisen

  1. Beachten Sie, dass ich anstelle von Zeichenfolgenliteralen Parameterplatzhalter verwendet habe, da man eigentlich parametrisierte Anweisungen verwenden sollte, um sich gegen SQL-Injection-Angriffe zu verteidigen .
eggyal
quelle
Du da Mann! Funktioniert wie ein Zauber, um jetzt einen Weg zu finden, dies vor Injektionen zu schützen. Ich sende die Daten an die Datenbank, nachdem die Benutzer ihr Abonnement für den Newsletter mit den in der Zeichenfolge angegebenen Parametern bestätigt haben. Irgendeine Idee, wie man das sichert? Danke
Laurence Cooper
1
@RehbanKhatri: Oh, sorry, ich dachte du meinst in der VALUES()Klausel. Die VALUES()Funktion übernimmt nur den Namen der Spalte, deren Wert aus der VALUES()Klausel stammt, die Sie verwenden möchten: Es ist lediglich eine Abkürzung, um zu verhindern, dass Sie sich wiederholen. du musst es nicht benutzen. Sie können Ihre Funktion einfach direkt in der SETKlausel verwenden, wenn Sie möchten, z SET column = MYFUNCTION().
Eggyal
1
Mmmh, das hat Sinn, ich habe gerade einen Artikel darüber gelesen, vielleicht ist der Artikel falsch. percona.com/blog/2010/07/14/…
amdev
1
@amdev: Das ist ein interessanter Artikel, der sich mit einigen sehr einfachen Details der MySQL-API für die Speicher-Engine befasst, von denen ich nichts wusste. Vielen Dank, dass Sie mich auf den neuesten Stand gebracht haben. Ich würde es dennoch vorziehen, meine gewünschte Logik so klar wie möglich auszudrücken, um die zukünftige Wartbarkeit zu unterstützen: Nur wenn die anderen oben genannten Bedenken nicht relevant sind und eine wesentliche Auswirkung auf die Leistung haben, würde ich in Betracht ziehen, zu wechseln, REPLACEwenn ich es wirklich beabsichtige aktualisieren. Denken Sie an Knuths Maxime: " Vorzeitige Optimierung ist die Wurzel allen Übels" .
Eggyal
3
@joseph: " Mit ON DUPLICATE KEY UPDATEist der Wert für betroffene Zeilen pro Zeile 1, wenn die Zeile als neue Zeile eingefügt wird, 2, wenn eine vorhandene Zeile aktualisiert wird, und 0, wenn eine vorhandene Zeile auf ihre aktuellen Werte gesetzt wird. "
eggyal
-2

Versuche dies:

INSERT INTO `center_course_fee` (`fk_course_id`,`fk_center_code`,`course_fee`) VALUES ('69', '4920153', '6000') ON DUPLICATE KEY UPDATE `course_fee` = '6000';
Manish Kumar
quelle
Dieses SQL-Skript enthält Tabellen / Spalten, die nichts mit dem OP-Schema zu
tun haben