Thread Insert Into... On Duplicate Key Update... (20 answers)
Opened by rosti at 2012-05-25 20:39

rosti
 2012-06-10 20:18
#158866 #158866
User since
2011-03-19
3492 Artikel
BenutzerIn
[Homepage]
user image
2012-05-29T08:39:51 pq
ich glaube es geht nicht ums update, sondern um das schema an sich. wenn du den datensatz irgendwo in einer anderen tabelle referenzieren willst, musst du dort immer das textfeld benutzen. ein integer als pk wäre da wohl deutlich platzsparender.


Das ist richtig, danke pq. Was MySQL betrifft gibt es doch noch eine kleine Sache, die ich bis jetzt übersehen habe:

LAST_INSERT_ID()
LAST_INSERT_ID(expr)

Issue: In eine Detailtabelle fließen Daten ein, von der Quelle aus gesehen, gibt es einen Unique Key, im eigenen DB-Design soll diese Detailtabelle jedoch einen auto_increment Wert bekommen.

Beim Datentransfer gibt es zwei Fälle:
- aufgrund des Unique Key ist der Record in meiner Tabelle schon vorhanden
- der Record ist neu (auch aufgrund des Unique Key)

In beiden Fällen wird beim Rausgehen aus der Funktion die id benötigt. Lt. MySQL kann LAST_INSERT_ID() auch im Fall zwei die id liefern, nämlich, wenn vorher LAST_INSERT_ID(expr) angewandt wurde. Die gewünschte expr ist in meinem Beispiel der Feldname id (auto_increment).

Somit kann auch eine bereits vorhandene id mit LAST_INSERT_ID() abgefragt werden, ein eigender Code ist dazu nicht notwendig.

Beispiel:
INSERT INTO user(user_id, user_name)VALUES(?,?)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# nutze die Möglichkeit der DB Engine
# und nutze einen eigenen Cache
sub insert_engine{
        state %cache = (); # feature 5.010
        my $r = shift;
        my @args = ($r->{user_id}, $r->{user_name});
        my $ck = $r->{user_id}.$r->{user_name};
        $cache{$ck} ||= eval{
                print "Anfrage\n"; # test ob der cache funktioniert
                $STH_INSERT_ON_DUPLICATE_KEY->execute(@args);
                $DBH->selectrow_array("SELECT LAST_INSERT_ID()");
        };
        return $@ ? undef : $cache{$ck};
}


Code getestet, Benchmark: Auch ohne Cache ok. Ein eigener Code zur _vorherigen Abfrage der id mit anschließender Entscheidung ob Insert ist NICHT schneller.

Viele Grüße,
Rosti

View full thread Insert Into... On Duplicate Key Update...