Warnung unterbinden

Warnung unterbinden

am 10.10.2007 21:42:13 von Knut Krueger

Hallo zusammen

ich möchte herausfinden ob es den Eintrag schon gibt:

$query = "SELECT Id FROM user WHERE Id = 5;
$result = mysql_query($query);
$test = mysql_result($result,"Id");

Klappt eigetnlich ganz gut, nur gibt es auf dem Schirm eine Warnung
Unable to jump to row 0 on MySQL result index ... wenn es den Eintrag
noch nicht gibt.

Gibt es eine bessere Lösung um Abzufragen ob der Wert schon in der
Spalte ist oder ein Möglichkeit die Warnung zu unterbinden?


Viele Grüße Knut

Re: Warnung unterbinden

am 10.10.2007 21:56:57 von Sebastian Suchanek

Thus spoke Knut Krueger:

> ich möchte herausfinden ob es den Eintrag schon gibt:
>
> $query = "SELECT Id FROM user WHERE Id = 5;
> $result = mysql_query($query);
> $test = mysql_result($result,"Id");
> [...]

Das ist alles mögliche (ja, ich habe einen dringenden Verdacht,
was das ist), aber kein (My)SQL.

> Gibt es eine bessere Lösung um Abzufragen ob der Wert schon
> in der Spalte ist oder ein Möglichkeit die Warnung zu
> unterbinden?

Wirf mal einen Blick auf "COUNT()" in der MySQL-Dokumentation.


Tschüs,

Sebastian

--
http://www.baumaschinen-modelle.net
http://www.schwerlast-rhein-main.de

Re: Warnung unterbinden

am 10.10.2007 22:17:31 von B.Steinbrink

On Wed, 10 Oct 2007 21:42:13 +0200, Knut Krueger wrote:

> Hallo zusammen
>
> ich möchte herausfinden ob es den Eintrag schon gibt:
>
> $query = "SELECT Id FROM user WHERE Id = 5; $result =
> mysql_query($query);
> $test = mysql_result($result,"Id");

PHP ist hier off-topic

> Klappt eigetnlich ganz gut, nur gibt es auf dem Schirm eine Warnung
> Unable to jump to row 0 on MySQL result index ... wenn es den Eintrag
> noch nicht gibt.
>
> Gibt es eine bessere Lösung um Abzufragen ob der Wert schon in der
> Spalte ist oder ein Möglichkeit die Warnung zu unterbinden?

Wenn du dem Leser deines SQLs auch gleich explizit mitteilen willst, dass
geprüft wird, ob ein Wert existiert:
SELECT EXISTS (SELECT * FROM user WHERE Id = 5);

Björn

Re: Warnung unterbinden

am 11.10.2007 11:36:54 von Andreas Scherbaum

Hallo Knut,

Knut Krueger wrote:

abgesehen davon, das PHP hier offtopic ist:

> ich möchte herausfinden ob es den Eintrag schon gibt:
>
> $query = "SELECT Id FROM user WHERE Id = 5;
> $result = mysql_query($query);

An dieser Stelle fehlt eine Prüfung, ob dein Query erfolgreich war.

> $test = mysql_result($result,"Id");

An dieser Stelle bietet PHP auch Möglichkeiten, die Anzahl zurück-
gelieferter Zeilen festzustellen. Die Doku wird dir ab hier gute
Dienste leisten.


Bis dann

--
Andreas 'ads' Scherbaum
Failure is not an option. It comes bundled with your Microsoft product.
(Ferenc Mantfeld)

Re: Warnung unterbinden

am 11.10.2007 13:32:58 von Knut Krueger

Andreas Scherbaum schrieb:
> Hallo Knut,
>
> Knut Krueger wrote:
>
> abgesehen davon, das PHP hier offtopic ist:
Sorry, aber die Kernfrage eingentlich nicht.
Das nächste mal frage ich ohne PHP Text ... Copy and Paste war einfacher ...

wie Björn geschrieben hat gibt es
SELECT EXISTS (SELECT * FROM user WHERE Id = 5);
und da wird es dann wohl auch in PHP keine Fehlermeldung geben.
>
>...
> An dieser Stelle fehlt eine Prüfung, ob dein Query erfolgreich war.
>
Das steht schon im weiteren Quelltext,denn wenn der Eintrag vorhanden
ist brauche ich ihn ja auch , nur kommt die Fehlermeldung eben schon bei
mysql_query..


Danke an alle Knut

Re: Warnung unterbinden

am 11.10.2007 13:53:57 von B.Steinbrink

On Thu, 11 Oct 2007 13:32:58 +0200, Knut Krueger wrote:

> Andreas Scherbaum schrieb:
>> Hallo Knut,
>>
>> Knut Krueger wrote:
>>
>> abgesehen davon, das PHP hier offtopic ist:
> Sorry, aber die Kernfrage eingentlich nicht. Das nächste mal frage ich
> ohne PHP Text ... Copy and Paste war einfacher ...
>
> wie Björn geschrieben hat gibt es
> SELECT EXISTS (SELECT * FROM user WHERE Id = 5); und da wird es dann
> wohl auch in PHP keine Fehlermeldung geben.
>>
>>...
>> An dieser Stelle fehlt eine Prüfung, ob dein Query erfolgreich war.
>>
> Das steht schon im weiteren Quelltext,denn wenn der Eintrag vorhanden
> ist brauche ich ihn ja auch , nur kommt die Fehlermeldung eben schon bei
> mysql_query..

Laut deinem ersten Posting kam der aber bei mysql_result. Oops, off-
topic...

Und wenn du die Zeile brauchst, falls sie existiert, ist der Ansatz
Quatsch, dann versuchst du einfach sie zu holen und wirst ja sehen, ob du
nen Ergebnis erhälst. Erst nur die (eh schon bekannte) Id abzufragen, um
im Erfolgsfall weitere Daten zu holen ist Unfug. (Ich hab deine jetzige
Formulierung zumindest so verstanden, dass du das so machst).

Solche Fälle mit nur einer einzigen Ergebniszeile lassen sich recht
schick mit den (eh zu bevorzugenden) mysql_fetch_* Funktionen
behandeln... Ach Mist aber auch, schon wieder off-topic... ;-)

Also ist dein Kern-Problem entweder nen falscher Ansatz, oder doch PHP ;-)

Björn

Re: Warnung unterbinden

am 11.10.2007 14:45:57 von Andreas Scherbaum

Knut Krueger wrote:
> Andreas Scherbaum schrieb:
>> Hallo Knut,
>>
>> Knut Krueger wrote:
>>
>> abgesehen davon, das PHP hier offtopic ist:
> Sorry, aber die Kernfrage eingentlich nicht.
> Das nächste mal frage ich ohne PHP Text ... Copy and Paste war einfacher ...

Ich glaube doch.

Du kannst natürlich auch versuchen, das Problem in SQL zu lösen, das wäre
an der Stelle aber unpassend. Wie gesagt, PHP bietet Funktionen, um die
Anzahl der Ergebnisse zu erfahren, diese solltest du nutzen und daraufhin
in deiner Applikation entsprechend reagieren.


> wie Björn geschrieben hat gibt es
> SELECT EXISTS (SELECT * FROM user WHERE Id = 5);
> und da wird es dann wohl auch in PHP keine Fehlermeldung geben.

Doch, kann es.

Beispiel:
Du hast in deinem Fall sicherlich keine Transaktion offen, also kann sich
die Datenmenge zwischendurch ändern. Dein erster Query fragt ab und erfährt,
das die Daten existieren, zwischendurch löscht jemand den User. Dein
darauffolgender Query bekommt keine Daten mehr und wirft wieder eine
Fehlermeldung.

Abgesehen davon, das du den Query zwei mal ausführen musst, während
eine Lösung in PHP nur eine Anfrage braucht.


> nur kommt die Fehlermeldung eben schon bei mysql_query..

Nein, die Fehlermeldung kommt erst, wenn du das nicht vorhandene Resultat
abrufen möchtest, nicht schon, wenn du den Query stellst.


Bye

--
Andreas 'ads' Scherbaum
Failure is not an option. It comes bundled with your Microsoft product.
(Ferenc Mantfeld)

Re: Warnung unterbinden

am 11.10.2007 15:44:03 von Knut Krueger

Andreas Scherbaum schrieb:

>> nur kommt die Fehlermeldung eben schon bei mysql_query..
>
> Nein, die Fehlermeldung kommt erst, wenn du das nicht vorhandene Resultat
> abrufen möchtest, nicht schon, wenn du den Query stellst.
>
Ich sollte um mein Gedächtnis aufzufrischen vor dem Antworten mein
eigenes Posting lesen.

> Und wenn du die Zeile brauchst, falls sie existiert, ist der Ansatz
> Quatsch, dann versuchst du einfach sie zu holen und wirst ja sehen, ob du
> nen Ergebnis erhälst. Erst nur die (eh schon bekannte) Id abzufragen, um
> im Erfolgsfall weitere Daten zu holen ist Unfug. (Ich hab deine jetzige
> Formulierung zumindest so verstanden, dass du das so machst).
Nun weiß ich nicht ob es off oder on topic ist.
Es dreht sich darum ob ein Bericht mit
Insert neu geschrieben wird oder mit UPDATE geändert wird.
Die ID wird von der aufrufenden Seite mitgeliefert.
Und deshalb muss ich wissen ob die ID schon vorhanden ist.

Viele Grüße Knut

Re: Warnung unterbinden

am 11.10.2007 16:14:16 von Christian Kirsch

Am 11.10.2007 15:44 schrieb Knut Krueger:

> Es dreht sich darum ob ein Bericht mit
> Insert neu geschrieben wird oder mit UPDATE geändert wird.

REPLACE existiert.


--
Christian

Re: Warnung unterbinden

am 11.10.2007 21:25:21 von Thomas Rachel

Knut Krueger schrieb:

> Nun weiß ich nicht ob es off oder on topic ist.

Ganz einfach: On-Topic ist es, wenn es

a) reines SQL ist oder
b) die MySQL-C-API-Funktionen in ihrer "reinen Form" betrifft.

Da in PHP (zumindest in bezug auf die mysql_*-Funktionen) b) nicht
zutrifft, weil die Syntax teilweise stark abweicht, ist PHP hier
off-topic. (Bei mysqli_* könnte man sich streiten, da ist die
Kompatibilität zur C-API eher vorhanden, aber auch da würde ich zu
de.comp.lang.php.datenbanken raten.


> Es dreht sich darum ob ein Bericht mit
> Insert neu geschrieben wird oder mit UPDATE geändert wird.
> Die ID wird von der aufrufenden Seite mitgeliefert.
> Und deshalb muss ich wissen ob die ID schon vorhanden ist.

INSERT ... ON DUPLICATE KEY UPDATE ... existiert.

HTH,


Thomas

Re: Warnung unterbinden

am 12.10.2007 09:08:28 von Kris

Knut Krueger wrote:
> Es dreht sich darum ob ein Bericht mit
> Insert neu geschrieben wird oder mit UPDATE geändert wird.
> Die ID wird von der aufrufenden Seite mitgeliefert.
> Und deshalb muss ich wissen ob die ID schon vorhanden ist.

Gegeben

mysql> create table t ( id integer unsigned not null primary key
auto_increment, d varchar(20) not null );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t (d) value ("old value");
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+----+-----------+
| id | d |
+----+-----------+
| 1 | old value |
+----+-----------+
1 row in set (0.00 sec)


MySQL hat eine Reihe von Methoden, mit denen Du den INSERT-UPDATE-Fall
eleganter abhandeln kannst.

1. INSERT IGNORE (Alter Wert hat Vorrang)

Du versuchst, einen Datensatz in die Tabelle einzufügen. Wenn das nicht
gelingt, wird der Fehler ignoriert. Mit der Funktion mysql_affected_rows()
bekommst Du eine Rückmeldung, ob ein Insert stattgefunden hat oder nicht.

mysql> insert ignore into t (id, d) values (1, "new value");
Query OK, 0 rows affected (0.00 sec)

mysql> insert ignore into t (id, d) values (2, "second value");
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+----+--------------+
| id | d |
+----+--------------+
| 1 | old value |
| 2 | second value |
+----+--------------+
2 rows in set (0.00 sec)


2. REPLACE (Delete-Insert Combo)

Du versuchst einen Datensatz in einer Tabelle zu ersetzen. MySQL nimmt die
Where-Clause und führt ein Delete durch. Danach wird Replace wie Insert
ausgeführt.

Mit der Funktion mysql_affected_rows() kannst Du erkennen, ob eine Löschung
von einer oder mehreren Zeilen stattgefunden haben (Affected Rows ist > 1)
und ein Insert stattgefunden haben oder nur ein Insert (Affected Rows ist
1).

mysql> replace into t (id, d) values (1, "new value");
Query OK, 2 rows affected (0.00 sec)

mysql> replace into t (id, d) values (2, "second value");
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+----+--------------+
| id | d |
+----+--------------+
| 1 | new value |
| 2 | second value |
+----+--------------+
2 rows in set (0.00 sec)

Beachte, daß Replace ein Delete-Insert ist, kein Update. Wenn die angegebene
Zeile nicht komplett ist, werden für die fehlenden Spalten Defaultwerte
eingesetzt. Partielle Updates sind so nicht möglich.

3. INSERT ... ON DUPLICATE KEY UPDATE ...

Das Kommando versucht einen Insert in die Tabelle t durchzuführen. Wenn es
dabei zur Verletzung einer Unique-Constraint kommt, wird die Update-Clause
durchgeführt.

Dies kann zu einer ganzen Menge unerwarteter Effekte führen, wenn mehr als
eine Unqiue Constraint existiert und sich das Insert und das Update
partiell wiedersprechen. Es ist sehr wichtig, hier den passenden Abschnitt
im Handbuch zu lesen und zu verstehen, wenn man eine solche Situation hat.

Bei einer Tabelle mit nur einer Unique Constraint (dem Primary Key)
funktioniert das Kommando aber wie erwartet.

Wieder ist mysql_affected_rows() hilfreich, um zu erkennen was genau
passiert ist.

mysql> insert into t (id, d) values (1, "new value") on duplicate key update
d = "new value";
Query OK, 2 rows affected (0.00 sec)

mysql> insert into t (id, d) values (2, "second value") on duplicate key
update d = "second value";
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+----+--------------+
| id | d |
+----+--------------+
| 1 | new value |
| 2 | second value |
+----+--------------+
2 rows in set (0.00 sec)


Oh, und natürlich ist das hier ontopic.

Kris

--
Kristian =?iso-8859-15?q?Köhntopp?=

Re: Warnung unterbinden

am 12.10.2007 09:33:13 von B.Steinbrink

On Fri, 12 Oct 2007 09:08:28 +0200, Kristian Köhntopp wrote:

> 2. REPLACE (Delete-Insert Combo)
>
> Du versuchst einen Datensatz in einer Tabelle zu ersetzen. MySQL nimmt
> die Where-Clause und führt ein Delete durch. Danach wird Replace wie
> Insert ausgeführt.

Hm, Where-Clause existiert ja im REPLACE Statement gar nicht, kann MySQL
also nicht einfach "nehmen". Sollte das nicht eher irgendwas wie "MySQL
generiert anhand der Unique Constraints eine Where-Clause mit der
zunächst ein DELETE ausgeführt wird" sein?

Björn

Re: Warnung unterbinden

am 12.10.2007 10:24:17 von Kris

Björn Steinbrink wrote:
> Hm, Where-Clause existiert ja im REPLACE Statement gar nicht, kann MySQL
> also nicht einfach "nehmen". Sollte das nicht eher irgendwas wie "MySQL
> generiert anhand der Unique Constraints eine Where-Clause mit der
> zunächst ein DELETE ausgeführt wird" sein?

Ja. Ich lallte, Du hast Recht.

Kris

--
Kristian =?iso-8859-15?q?Köhntopp?=

Re: Warnung unterbinden

am 12.10.2007 11:49:46 von Axel Schwenke

Kristian =?UTF-8?B?S8O2aG50b3Bw?= wrote:
>
> Ja. Ich lallte, Du hast Recht.

An dieser Stelle mußte ich LOLlen :)


XL