ubuntuusers.de

[SQLite] Insert or replace mit where

Status: Gelöst | Ubuntu-Version: Ubuntu 12.10 (Quantal Quetzal)
Antworten |

Developer92 Team-Icon

Avatar von Developer92

Anmeldungsdatum:
31. Dezember 2008

Beiträge: 4101

Hallo, ich habe da ein Problem: In meiner SQLite-Datenbank soll abhängig von einer x und y-Koordinate ein Text gespeichert werden. Leider haut das mit dem "where" nicht so ganz hin:

sqlite> create table coords (id integer primary key autoincrement, x integer, y integer, typ text);
sqlite> insert into coords values(null, 0, 0, 'blau');
sqlite> insert into coords values(null, 0, 1, 'schwarz');
sqlite> insert into coords values(null, 1, 1, 'rot');
sqlite> insert into coords values(null, 1, 0, 'gelb');
sqlite> select * from coords;
1|0|0|blau
2|0|1|schwarz
3|1|1|rot
4|1|0|gelb
sqlite> select * from coords where x=0 and y=1;
2|0|1|schwarz
sqlite> insert or replace into coords values(null, 0, 1, 'gruen') where x=0 and y=1;
Error: near "where": syntax error

Es geht um folgendes: Wenn ein Eintrag mit entsprechender x und y-Koordinate noch nicht existiert, soll dieser erzeugt werden (mittels insert). Existiert bereits ein Eintrag mit entsprechender x und y-Koordinate soll der entsprechende Datenbankeintrag ersetzt werden (wobei die ersten 3 Werte gleich bleiben, lediglich der Wert "typ" soll aktualisiert werden.

Kann ich das irgendwie in nur eine DB-Abfrage quetschen?

Hab leider nichts funktionierendes dazu gefunden (oder bin ich mit insert or replace aufm Holzweg?)

mfg

fckawe

Avatar von fckawe

Anmeldungsdatum:
23. April 2011

Beiträge: 509

Wohnort: Freiburg im Breisgau

Hallo,

ich kenne mich zwar nicht so wirklich mit der Syntax für SQLite aus, aber ein Insert mit Where ist ja normalerweise unsinnig. Gut, da ist noch das "or replace", das ich eben nicht kenne. Aber lt. der Doku gibt es da auch wirklich kein Where.

Ich würde ja vermuten, dass der Replace automatisch funktioniert. Wenn schon ein Satz mit dem selben Schlüssel (!) vorhanden ist, dann wird der halt überschrieben, anstatt dass ein Fehler kommt. Allerdings sind die Koordinaten bei dir ja nicht im Schlüssel.

Gruß, Gerald

Developer92 Team-Icon

(Themenstarter)
Avatar von Developer92

Anmeldungsdatum:
31. Dezember 2008

Beiträge: 4101

fckawe schrieb:

Hallo,

ich kenne mich zwar nicht so wirklich mit der Syntax für SQLite aus, aber ein Insert mit Where ist ja normalerweise unsinnig.

Dachte ich Anfangs auch, aber hier in meinem Fall wäre es praktisch.

Gut, da ist noch das "or replace", das ich eben nicht kenne. Aber lt. der Doku gibt es da auch wirklich kein Where.

Hm, stimmt.

Ich würde ja vermuten, dass der Replace automatisch funktioniert. Wenn schon ein Satz mit dem selben Schlüssel (!) vorhanden ist, dann wird der halt überschrieben, anstatt dass ein Fehler kommt. Allerdings sind die Koordinaten bei dir ja nicht im Schlüssel.

Richtig. Dann muss ich den Key wohl doch seperat speichern um anschließend neue Werte reinschreiben zu können.

Oder eben zuvor ein "select * where x=? and y=?" ausführen um den Schlüssel rauszubekommen. Kostet halt alles Rechenzeit und das ganze sollte eigentlich so schnell wie möglich ablaufen.

mfg

EDIT: Nochmal zu dem hier:

Ich würde ja vermuten, dass der Replace automatisch funktioniert. Wenn schon ein Satz mit dem selben Schlüssel (!) vorhanden ist, dann wird der halt überschrieben, anstatt dass ein Fehler kommt.

Das wäre ja von mir so gewollt. Die Datensätze enhalten ja jeweils Koordinaten mit Eigenschaften zu den Koordinaten. Und wenn sich die Eigenschaften ändern muss sich auch die Datenbank entsprechend abändern, damit das alles schön synchron bleibt =)

Developer92 Team-Icon

(Themenstarter)
Avatar von Developer92

Anmeldungsdatum:
31. Dezember 2008

Beiträge: 4101

Ich glaube ich hab ne Lösung gefunden. In SQLite ist es möglich, mehr als einen PK zu definieren:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
sqlite> create table test (x integer, y integer, colour test, primary key (x, y));
sqlite> insert into test values(0,0, 'blau');
sqlite> insert into test values(0,0, 'rot');
Error: columns x, y are not unique
sqlite> insert into test values(0,1, 'rot');
sqlite> insert into test values(1,1, 'gelb');
sqlite> insert into test values(1,0, 'gruen');
sqlite> select * from test;
0|0|blau
0|1|rot
1|1|gelb
1|0|gruen
sqlite> insert or replace into test values(0,0, 'lila');
sqlite> select * from test;
0|1|rot
1|1|gelb
1|0|gruen
0|0|lila
sqlite> .quit

Bisher genau das, was ich gesucht habe. Hoffentlich gibts da nicht Nebenwirkungen ☺

mfg

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Developer92 schrieb:

Ich glaube ich hab ne Lösung gefunden. In SQLite ist es möglich, mehr als einen PK zu definieren:

Hu? Das ist kein Feature von SQLite, sondern ein *grundlegendes Konzept* von relationalen DBs... 😉 Bist Du sicher, dass Du die Funktion von PKs und FKs wirklich verstanden hast - und damit das relationale Konzept per se?

Developer92 Team-Icon

(Themenstarter)
Avatar von Developer92

Anmeldungsdatum:
31. Dezember 2008

Beiträge: 4101

Lysander schrieb:

Bist Du sicher, dass Du die Funktion von PKs und FKs wirklich verstanden hast - und damit das relationale Konzept per se?

Nein, klär mich auf ☺

mfg

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Developer92 schrieb:

Nein, klär mich auf ☺

Na, das kannste selber machen 😉

Developer92 Team-Icon

(Themenstarter)
Avatar von Developer92

Anmeldungsdatum:
31. Dezember 2008

Beiträge: 4101

Lysander schrieb:

Developer92 schrieb:

Nein, klär mich auf ☺

Na, das kannste selber machen 😉

Danke ☺

Nachdem ich aber jetzt weiß, dass mehrere PKs in einer relationalen Datanbank vorgesehen sind, komme ich zu folgender Frage:

Kann man [in SQLite] mehrere PKs definieren, die aber trotzdem jeweils eindeutig sein müssen?

Sodass man zum Beispiel für Firmen in einer Datenbank eine interne Bezeichnung für ein Produkt als PK definiert und zusätzlich noch aber auch für externe Firmen einen 2. PK. Oder muss man dazu das Schlüsselwort unique verwenden?

mfg

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

PKs sind per definition unique und not null - das ist quasi die Definition 😉

Wenn Du einen zusammengesetzten PK hast und es Nichtschlüsselattribute gibt, die nur von einem Teil des PK abhängen, so ist die zweite Normalform verletzt. Das willst Du nicht wirklich 😉 Man geht in der Praxis davon aus, dass man eine DB immer in der dritten Normalform halten sollte.

Antworten |