INSERT aber nur UPDATE wenn schon vorhanden

ramboni

Benutzer
Beiträge
17
Hallo zusammen,

ich bin relativ neu im Thema und habe da ein paar Grundsatzfragen.
Ich habe eine Tabelle (id, erzeugt, aktualisiert,Telefonnummer)
Dort kann ich bereits nach Lust und Laune Datensätze hinzufügen.

Wenn nun jedoch ein Feld, Telefonnummer bereits vorhanden ist, soll er keinen neuen Datensatz
einfügen sondern einfach das Feld "aktualisiert" mit dem aktuellen Datum updaten.

Alle beispiele die ich gefunden habe wollen irgendwas mit der id... ich verstehe nicht wie das gehen soll da ich ja von der doppelten telefonnummer keine id habe, ich muss also irgendwie prüfen ob der string telefonnummer bereits vorhanden ist, wenn ja: Update(aktualsiert) wenn nein neuen Datensatz anlegen.

Klingt simpel, ist es für mich jedoch nicht... :(
Evtl. hat gerade ein erfahrener User Zeit mir so etwas siples zu erkläen :)
 
Werbung:
ich würde es so machen...

Code:
CREATE TABLE
edb=*# insert into telefon values ('1234', 'Hans', now()) on conflict (nummer) do update set aktualisiert = now();
INSERT 0 1
edb=*# commit;
COMMIT
edb=# select * from telefon ;
 nummer | name |       aktualisiert       
--------+------+---------------------------
 1234   | Hans | 06-JUL-21 17:36:08.564299
(1 row)

edb=*# insert into telefon values ('1234', 'Hans', now()) on conflict (nummer) do update set aktualisiert = now();
INSERT 0 1
edb=*# commit;
COMMIT
edb=# select * from telefon ;
 nummer | name |       aktualisiert       
--------+------+---------------------------
 1234   | Hans | 06-JUL-21 17:36:23.508598
(1 row)

edb=*# insert into telefon values ('2345', 'Susi', now()) on conflict (nummer) do update set aktualisiert = now();
INSERT 0 1
edb=*# select * from telefon ;
 nummer | name |       aktualisiert       
--------+------+---------------------------
 1234   | Hans | 06-JUL-21 17:36:23.508598
 2345   | Susi | 06-JUL-21 17:36:31.196536
(2 rows)

edb=*#

Das war jetzt vereinfacht von Deiner Tabelle. Wenn die Telefonnummer (die ja sicherlich eindeutig ist) schon da ist und Du eine ID-Spalte als Primary Key hast, dann ist der Konflict halt auf dieser Spalte, und zusätzlich, falls ein UNIQUE CONSTRAINT auf der Tel-Nummer ist, auch auf dieser. Beide kannst Du nutzen.

Alternativ: erstelle einen TRIGGER.
 
Also muss ich die ID mit dem PK löschen und die telefonnummer als PK nutzen?
nein, nicht nötig. Vielleicht willst Du die ID ja auch noch für eine andere Tabelle als FK nutzen, um dort mehrere Telefone einer Person zuzuordnen, das geht besser mit einer generierten ID als der eigentlichen Nummer.
 
Zuletzt bearbeitet:
Funktioniert leider nicht.... (ich teste mit xampp)

Server: 127.0.0.1 via TCP/IP
Server-Typ: MariaDB
Server-Verbindung: SSL wird nicht verwendet Dokumentation
Server-Version: 10.3.15-MariaDB - mariadb.org binary distribution
Protokoll-Version: 10
Benutzer: root@localhost
Server-Zeichensatz: cp1252 West European (latin1)




Fehler

Statische Analyse:

3 Fehler wurden während der Analyse gefunden.

Unerwartetes Zeichen. (near "conflict" at position 51)
Unerwarteter Statement-Anfang. (near "conflict" at position 51)
Unerwarteter Statement-Anfang. (near "nummer" at position 61)

SQL-Befehl: Kopieren

insert into test values ('1234', 'Hans', now()) on conflict (nummer) do update set aktualisiert = now();

MySQL meldet: Dokumentation
#1064 - Fehler in der SQL-Syntax. Bitte die korrekte Syntax im Handbuch nachschlagen bei 'conflict (nummer) do update set aktualisiert = now()' in Zeile 1
 
Sorry, aber das hier ist doch die "MySQL und MariaDB" Sektion, wenn du die Antwort nicht kennst, dann antworte bitte nicht.

Wie es theoretisch funktioniert weiß ich (If then else ist mir bekannt).
Ich habe auf ein funktionierendes Beispiel gehofft aus dem ich weitere Rückschlüsse ziehen und lernen kann.
Alle Beispiele die ich gefunden habe beziehen sich auf eine Verbindung zwischen einem Feld und einer ID.
Wo ich den zusammenhang nicht verstehe, was wiederum der Grund war hier zu schreiben.
 
Alle Beispiele die ich gefunden habe beziehen sich auf eine Verbindung zwischen einem Feld und einer ID.
Wo ich den zusammenhang nicht verstehe, was wiederum der Grund war hier zu schreiben.

Etwas unklar jetzt, was für Dich unklar ist. Typischerweise generiert man via einer automatisch generierten ID einen Primary Key. Wenn Du bereits einen natürlichen eindeutigen Schlüssel hast (wie Tel-Nummer oder Mailadresse oder so) kannst Du das auch als Primary Key nutzen - muß man aber nicht. Oft ist es sinnvoller, dennoch eine ID zu generieren.

Um eine Telefonnummer also eindeutig zu machen, kannst Du die Spalte als NOT NULL und UNIQUE definieren. Damit kannst Du diese Telefonnummer nicht mehrfach eingeben, Dein Problem, Zitat: "da ich ja von der doppelten telefonnummer keine id habe" löst sich damit in Luft auf.

Nun mußt Du nur noch aufpassen, wie Du eventuelle Konflikte (selbe Telefonnummer wird wieder eingegeben) löst. Dafür gibt es in unterschiedlichen Datenbanken unterschiedliche Wege - je nachdem, wie gut die DB ist ...

Wenn Du die von mir gezeigte Syntax, also "on conflict do update" gepaart mit "mysql" in eine Suchmaschine klimperst wirst vielleicht sogar fündig.
 
Tabelle:
- Test

Felder:
- ID [int(10), autoincrement, PK]
- Telefonnummer [varchar(255)]
- Name [varchar(255)]
- aktualisiert [datetime]

PHP
insert into test (telefonnummer,name) VALUES ("012345","Matrixuser")


Wenn ich nochmals die Telefonnummer 012345 einfügen möchte, soll er weder abbrechen, noch etwas melden sondern
einfach keinen neuen Datensatz hinzufügen sondern das Feld aktualisiert mit dem Tagesdatum überschreiben.

"Wenn Du die von mir gezeigte Syntax, also "on conflict do update" gepaart mit "mysql" in eine Suchmaschine klimperst wirst vielleicht sogar fündig."

Ja, dann bekomme ich ja genau die Antworten die ich nicht verstehe, wo alle Beispiel irgendwas von ID vorhanden reden...
ich habe aber nur bei den bereits gespeicherten Daten eine ID... ich kann also keine zweite ID übergeben.
Rein prozessual interessiert mich diese ID also gar nicht, es sei denn ich will später etwas damit verknüpfen. soweit bin ich aber noch nciht.

Wenn es die Telefonnummer schon gibt, aktualisiere das Datum sonst füge gesamten Datensatz neu ein.
Geht das überhaupt in nur einem Statement?
 
Hie genau das was ich nicht verstehe:

SELECT * FROM ins_duplicate;
+----+----------+
| id | animal |
+----+----------+
| 1 | Aardvark |
| 2 | Cheetah |
| 3 | Zebra |
| 4 | Gorilla |
+----+----------+


und dann wird gesagt, macht das so:

INSERT INTO ins_duplicate VALUES (1,'Antelope') ON DUPLICATE KEY UPDATE animal='Antelope';


Ich habe aber den Value 1 nicht beim hinzufügen.... woher auch?
Bei mir würde das so aussehen: INSERT INTO ins_duplicate VALUES ('Antelope')

und schon funktioert gar nicht mehr
 
Hallo Ramboni,

ich habe zwar auch nicht so viel Ahnung von MySQL (mein Bereich ist eher MS SQL Server) aber dein Beispiel im letzten Post ist schon der richtige Weg, genauso wie das Beispiel von akretschmer.
(Beim SQL Server ginge das ganz einfach mit einem MERGE-Statement, aber das kann MySQL nicht, daher ist der Ansatz mit ON DUPLICATE KEY UPDATE schon korrekt).

Es gibt hier eine schöne Beschreibung der Funktionsweise und der Bedingungen für den Befehl "ON DUPLICATE KEY UPDATE" : MySQL :: MySQL 5.7 Reference Manual :: 13.2.5.2 INSERT ... ON DUPLICATE KEY UPDATE Statement

Dieses INSERT funktioniert wohl so, dass bei einem Eintrag von Daten entweder ein PRIMARY KEY oder ein UNIQUE INDEX auf schon vorhandene Einträge geprüft wird.
Da du in deinem INSERT ja nur die Telefonnummer und einen Namen einträgst, musst du in der Tabelle nur einen UNIQUE INDEX auf das Feld Telefonnummer eintragen.
Dann wird mit der Prüfung "ON DUPLICATE KEY UPDATE" auch ein Update der dann angegebenen Felder und Daten vorgenommen.
Wichtig ist aber der UNIQUE INDEX, damit eine Key-Prüfung vorgenommen werden kann. Da du beim Insert das Feld ID nicht einträgst - die eindeutige Nummer sollte als Autowert automatisch vergeben werden - wird dies bei der Prüfung auf vorhandene Einträge im UNIQUE INDEX auch nicht berücksichtigt.

MySQL :: MySQL 5.7 Reference Manual :: 13.1.14 CREATE INDEX Statement

Viele Grüße,
Tommi
 
Werbung:
Danke Tommi,

dein Post hat zur Lösung geführt.


Für alle NewBs wie ich, hier die Lösung:

1. Tabelle erzeugen

XXDatenbankXX = Name der Datenbank
XXTabelleXX = Name der zu erzeugenden Tabelle

CREATE TABLE `XXDatenbankXX`.`XXTabelleXX` ( `id` INT NOT NULL AUTO_INCREMENT , `telefonnummer` VARCHAR(50) NOT NULL , `name` VARCHAR(255) NOT NULL , `aktualisiert` DATETIME NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;

2. Feld Telefonnummer als UNIQUE setzen

ALTER TABLE `test` ADD UNIQUE(`telefonnummer`);


3. So sieht das Insert Statement aus


insert into test (telefonnummer,name, aktualisiert) VALUES ("123","Thomas",now()) ON DUPLICATE KEY UPDATE aktualisiert = now()


Schönen Tag allen....
 
Zurück
Oben