Forum: PC-Programmierung mysql_real_query OR bust


von Matthias (Gast)


Lesenswert?

Hallo Community,

ich habe ein schoenes Prograemmchen, was fertig ist, laeuft und 
eigentlich tut, was es soll.

Bis auf nachstehenden Code-Block
1
  
2
if(mysql_real_query(mysql,mysql_query_string,strlen(mysql_query_string))){    print_error_info(); 
3
}
4
5
else{
6
  //tu was anders
7
}

wobei der mysql_query_string so aussieht:
SELECT * FROM zzz WHERE spalte_1='xxx' and spalte_2='yyy';

Ist der eingegebene mysql_query_string falsch, funktioniert das Programm 
trotzdem, genauso im Fall, wenn der string, wie oben, korrekt ist.

Bitte keine Hinweise auf die mysql-Dokumentation. Die empfiehlt die 
obige if-Bedingung.

p.s. Der mysql_query_string ist korrekt und funktioniert in mysql.

von Jim M. (turboj)


Lesenswert?

Versuche es mal ohne das Semokolon am Ende des Query Strings. Lass Dir 
in  print_error_info() den MySQL Fehler anzeigen, siehe mysql_error().

von Matthias (Gast)


Lesenswert?

Das Weglassen des Semikolons hat erwartungsgemaess nicht funktioniert. 
Haette mich auch gewundert, wird doch so jeder mysql-Befehl 
abgeschlossen.

mysql_error() werde ich ausprobieren.

von Test (Gast)


Lesenswert?

Doku lesen würde hier helfen... Der return code ist 0 im fall von 
"success" ..

von Matthias (Gast)


Lesenswert?

@Test
Danke fuer Deinen hilfreichen Tipp.

a) Das war bereits bekannt und

b) haettest Du einmal genauer gelesen, was ich oben geschrieben habe, 
dann haettest Du festgestellt, dass Dein Post auch ueberfluessig 
war,denn

ich habe geschrieben, dass die Funktion immer gleich reagiert, egal ob 
der mysql_string richtig oder falsch ist.

von Matthias (Gast)


Lesenswert?

@ Test

Um trollige Antworten zu vermeiden hatte ich eingangs erwähnt, dass 
keine Hinweise a la 'Hey guck einfach in die Dokumentation' erwünscht 
sind.

von olibert (Gast)


Lesenswert?

Matthias schrieb:
> @ Test
>
> Um trollige Antworten zu vermeiden hatte ich eingangs erwähnt, dass
> keine Hinweise a la 'Hey guck einfach in die Dokumentation' erwünscht
> sind.

Darf man die Dokumentation wenigstens zitieren ?

"Normally, the string must consist of a single SQL statement without a 
terminating semicolon (“;”) or \g."

Merkwuerdige Einstellung die hier manche Forenteilnehmer haben.

von Jens G. (jensig)


Lesenswert?

Reagiert der rc von mysql_real_query auch auf Errors auf SQL Ebene, die 
erst vom Server erkannt werden, oder evtl. nur auf Fehler beim 
API-Aufruf an sich?
Wenn ich die mysql_real_query Doku so anschaue, scheint wohl nur 
zweiteres zu gelten.
http://etutorials.org/SQL/MySQL/Part+II+Using+MySQL+Programming+Interfaces/Chapter+6.+The+MySQL+C+API/Processing+Queries/
macht auch so gewisse Andeutungen in der Richtung (explizite Abfrage mit 
mysql_errno()).

von olibert (Gast)


Lesenswert?

Jens G. schrieb:
> Reagiert der rc von mysql_real_query auch auf Errors auf SQL Ebene, die
> erst vom Server erkannt werden, oder evtl. nur auf Fehler beim
> API-Aufruf an sich?

Wuerde ich vermuten und scheint hier bestaetigt zu werden:

http://stackoverflow.com/questions/280421/multiple-mysql-real-query-in-while-loop

Es ist wahrscheinlich auch in der Dokumentation, aber ich bin jetzt zu 
faul die fuer jemand anders zu lesen.

von Matthias (Gast)


Lesenswert?

In Punkto Weglassen des Semikolons hattet Ihr Recht, mea culpa.

Ein Null terminated String liegt zwar vor, kann aber als Fehlerquelle 
ausgeschlossen werden, da hierfuer ja mysql_real_query() statt 
mysql_query() genutzt wird, so wie es die Dokumentation in solchen 
Faellen empfiehlt.

Einen globalen modifier in Form von '\g' liegt ebenfalls nicht vor.

Ich persönlich habe, nachdem ich in einem Buch einen Teilabsatz gelesen 
habe, einen ganz anderen Verdacht...

Wie gleich zu Beginn angemerkt wurde, gibt mysql_real_query im 
Erfolgsfall eine '0' zurück. Aber was ist eigentlich ein Erfolgsfall???

Mein Problem war nun, dass ich immer eine '0' zurück bekam, egal ob die 
übertragene Query, genauer gesagt deren Bestandteile, richtig oder 
falsch waren bzw. mit der mysql-DB uebereinstimmtem oder nicht.

Kann es sein, dass mysql_real_query einfach nur die Uebertragung der 
Anfrage als solche mit 0 ungleich 0 bewertet?

Nachstehend der Absatz ueber den ich gestolpert bin...

"Für Anfragen an den Server mit z. B. INSERT, wo ja nichts zurückgegeben 
wird, reichen mysql_query() und mysql_real_query() aus. Allerdings bei 
Anfragen mittels SELECT, SHOW, DESCRIBE oder EXPLAIN, wo etwas 
zurückgegeben wird, benötigen Sie eine Funktion, um die Daten der 
SQL-Abfrage abzuholen. Hierfür müssen Sie die Funktionen 
mysql_store_result() oder mysql_use_result() aufrufen."

Das wuerde ja bedeuten ich muss eine weitere Funktion einsetzen, um das 
Ergebnis meiner mittels mysql_real_query initiierten SELECT - Anweisung 
abzufangen um es dann mittels strcmp() zu vergleichen.

von olibert (Gast)


Lesenswert?

Mann, Mann, Mann, dass steht doch alles in der Dokumentation !

Zero wird zurueckgegeben, wenn keiner der unten angefuehrten Fehler 
aufgetreten ist.

http://dev.mysql.com/doc/refman/5.6/en/mysql-real-query.html

Return Values

Zero for success. Nonzero if an error occurred.
Errors

    CR_COMMANDS_OUT_OF_SYNC

    Commands were executed in an improper order.

    CR_SERVER_GONE_ERROR

    The MySQL server has gone away.

    CR_SERVER_LOST

    The connection to the server was lost during the query.

    CR_UNKNOWN_ERROR

    An unknown error occurred.

von Matthias (Gast)


Lesenswert?

LOESUNG

In der offiziellen Dokumentation steht, dass mysql_real_query() die 
Anfrage ausfuehrt. Wie ich bereits oben geschrieben habe, bin ich 
faelschlicherweise davon ausgegangen, dass hierbei auch eine 
Pruefung/Abfrage auf den von mir uebergebenen String erfolgen wuerde.

Wuerde dieser mit einem aus der DB ueberseinstimmen, gibt die Funktion 
'0' zurueck, so meine Annahme, aber das stimmt nicht.

Ich denke mal es wird hier lediglich auf die Validitaet der eigentlichen 
mysql-Anfrage hin ueberprueft, Syntax -what ever-

Um das umzusetzen, was ich eingangs beschrieben habe, naemlich einen 
Abgleich zwischen einem string und einem datenbankeintrag 
durchzufuehren, hat es noch zweier weiterer Funktionen bedurft.

mysql_fetch_row () : Gibt es Zeilen mit dem gesuchten Eintrag?

mysql_num_fields() : Ausgabe des mysql-Datensatzes (mehr o weniger)

Jetzt, nach der Ausgabe, kann ich einfach mittels strcmp() einen 
if-Block bauen und das umsetzen, was ich urspruenglich wollte.

Das war mein Eingangsposts

>Ist der eingegebene mysql_query_string falsch, funktioniert das Programm
>trotzdem, genauso im Fall, wenn der string, wie oben, korrekt ist.

welcher zeigt, dass ich mysql_real_query() missverstanden habe und nicht 
nur ich scheinbar.

Sollten Rueckfragen bestehen, wie die Implementierung im Einzelnen 
aussieht helfe ich gerne...

Wer will kann natürlich auch gerne auf die Dokumentation zurueckgreifen!

von Matthias (Gast)


Lesenswert?

@olibert

Du bist sehr aggressiv.

Dies ist ein Forum in dem man sich austauscht. Wuerde jeder auf die 
Dokumentation verweisen, waere das Forum obsolet.

Des Weiteren steht das so nicht in der Dokumentation.

Es steht vielleicht implizit drin.

Davon mal abgesehen, siehe meinen obigen Post. Mein Fehler war 
offensichtlich. Waerst Du so ein toller Hecht, wie Du hier vorgibst, 
waere Dir mein Fehler sofort aufgefallen und ein Satz haette zur Loesung 
des Problems gefuehrt.

MfG

von olibert (Gast)


Lesenswert?

Matthias, ich bin nicht agressiv. Du hast dich nur von Anfang an 
gesperrt auf die Dokumentation verwiesen zu werden und offensichtlich 
erwartet, dass das andere fuer dich tun. Das ist nicht der Sinn eines 
Forums.

Ich bin kein "toller Hecht", aber ich bin der Lage mir benoetigte 
Informationen aus dem Internet zusammen zu suchen bevor ich ein Forum 
bemuehe.

von Matthias (Gast)


Lesenswert?

>und offensichtlich erwartet, dass das andere fuer dich tun

Offensichtlich nicht.

Die Loesung habe ich mir selbst erarbeitet und habe sie anschliessend im 
Forum ausfuehrlich geteilt, falls es jemanden gibt, der vor einem 
aehnlichen Problem steht.

>Ich bin kein "toller Hecht", aber ich bin der Lage mir benoetigte
>Informationen aus dem Internet zusammen zu suchen bevor ich ein Forum
>bemuehe.

Ich bin von einem falschen Anfangssachverhalt ausgegangen, insofern ist 
meine durchaus erfolgte Suche immer in die falsche Richtung gelaufen, 
ich habe mich schlichtweg geirrt.

Auch habe ich grundsätzlich nichts gegen Dokumentationen, im Gegenteil.

Ich gebe Dir gerne ein Beispiel, wie es auch laufen kann!

Beitrag "Anfängerfrage: per .exe Wert in MySQL-Datenbank ändern"

Nachdem ich geantwortet habe, war der Threat zu, erledigt. Und Du kannst 
sicher sein, dass, haette er eine Rueckfrage gehabt, ich darauf 
eingegangen waere!

von Jens G. (jensig)


Lesenswert?

>mysql_fetch_row () : Gibt es Zeilen mit dem gesuchten Eintrag?

>mysql_num_fields() : Ausgabe des mysql-Datensatzes (mehr o weniger)

>Jetzt, nach der Ausgabe, kann ich einfach mittels strcmp() einen
>if-Block bauen und das umsetzen, was ich urspruenglich wollte.

Wenn Du nur prüfen willst, ob eine oder mehrere Rows mit den 
Suchkriterien existieren oder nicht (so hatte ich Dich anfangs mal 
verstanden), kann man mysql_errno bzw mysql_sqlstate auswerten. Da muß 
man nicht extra fetchen und Stringvergleiche machen.

von Matthias (Gast)


Lesenswert?

Du hast es schon richtig verstanden.

-> '00000' means “no error

Wenn ich das richtig interpretiere, wuerdest Du das dann so loesen... 
nachdem Du die mysql_real_query abgefeuert hast.
1
const char *state_value;
2
int rtn_value;
3
4
state_value = mysql_sqlstate(mysql);
5
6
rtn_value = strcmp(state_value,'00000');
7
8
if(rtn_value == '0'){
9
  //Pseudocode
10
  Uebereinstimmung gefunden
11
}
12
13
else{
14
  //Fehlermeldung
15
}

von Karl H. (kbuchegg)


Lesenswert?

Das kann ich mir nicht vorstellen, dass diese Vorgehensweise zielführend 
ist.

Ich hab mal die Liste der möglichen Errors durchgescrollt
http://dev.mysql.com/doc/refman/5.0/en/error-messages-server.html

Vielleicht hab ich auch den entscheidenden Error übersehen. Möglich.

Allerdings ist ein 0-Ergebnis eines SELECT für mich auch kein Error. Es 
ist ein ganz normales Ergebnis, das bei einer Datenbankabfrage vorkommen 
kann und wird auch als solches behandelt: Als ganz normales Ergebnis und 
nicht als Error.

Wenn man die Anzahl wissen will, dann kann man immer noch einen COUNT 
benutzen und kein SELECT. Aber abholen muss man das Ergebnis da wie 
dort. Weder ein leeres SELECT-Ergebnis noch ein COUNT-Ergebnis von 0 ist 
da ein Fehler. Und ich seh da ehrlich gesagt auch nicht ein, warum das 
ein Fehler sein sollte. Wenn ich etwas suche, dann muss ich immer damit 
rechnen, dass das Gesuchte nicht gefunden werden kann. Dieser Fall ist 
aber davon zu trennen, dass die Abfrage schon nicht korrekt formuliert 
wurde und deshalb die ganze Abfrage in sich gescheitert ist. Ist die 
Abfrage korrekt formuliert, gab es auch kein sonstiges technisches 
Problem, dann ist ein Ergebnis, das aus 0 Datensätzen besteht, genauso 
ein Ergebnis wie jedes andere auch.

: Wiederhergestellt durch User
von Matthias (Gast)


Lesenswert?

Um die Anzahl ging es mir nicht, vielmehr um das ob...

Naemlich ob meine 'SELECT' zutrifft oder nicht. Anders ausgedrueckt, ist 
mein Suchstring Bestandteil der DB/Tabelle/etc., ja/nein.

Da in der Dokumentation stand, dass mysql_sqlstate() im Falle einer 
fehlerfreien Abfrage '00000' zurueckgibt, war das Code-Beispiel aus 
meiner Sicht nicht so abwägig.

Ich führe doch meine mysql_real_query() aus und implementiere danach 
sofort den Ansatz von Jens.

Da sich mysql_sqlstate() lt. Dokumentation auf den 'code for the most 
recently executed SQL', also eben diese query, samt meiner 'SELECT' 
bezieht, müsste diese, vorbehaltlich sie ist valide und es gibt einen 
Treffer, Erfolg gehabt haben und somit '00000' ausgeben.

von Matthias (Gast)


Lesenswert?

@Karl-Heinz

Sicher, zu einem spaeteren Zeitpunkt muesste man sicher genauer 
differentieren zwischen einem Fehler, der aufgrund einer fehlerhaft 
formulierten Abfrage oder aber einfach auf Grund eines Nichtvorkommens 
des Suchstrings ausgelöst wird.

Jens hat eine neue Variante der Problemlösung angemerkt und ich wollte 
lediglich wissen, ob mein Gedanke der Umsetzung sachlogisch richtig ist, 
Feinheiten etc. einmal ausgenommen.

von Karl H. (kbuchegg)


Lesenswert?

Matthias schrieb:
> Um die Anzahl ging es mir nicht, vielmehr um das ob...
>
> Naemlich ob meine 'SELECT' zutrifft oder nicht. Anders ausgedrueckt, ist
> mein Suchstring Bestandteil der DB/Tabelle/etc., ja/nein.

Exakt.
Und wenn er Bestandteil ist, dann ist das Ergebnis eines COUNT größer 0.


> Da sich mysql_sqlstate() lt. Dokumentation auf den 'code for the most
> recently executed SQL', also eben diese query, samt meiner 'SELECT'
> bezieht, müsste diese, vorbehaltlich sie ist valide und es gibt einen
> Treffer, Erfolg gehabt haben und somit '00000' ausgeben.

valide: ohne Einschränkung ja
es gibt einen Treffer: würde ich aus dem Bauch heraus verneinen.

Aber: Versuch macht kluch.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Aber: Versuch macht kluch.

Der Grund, warum ich das einfach mal probieren würde, ist der hier
http://dev.mysql.com/doc/refman/5.0/en/mysql-field-count.html

von Matthias (Gast)


Lesenswert?

@ Karl-Heinz

Du hast Recht. Die COUNT > 0 Variante hatte ich schon auf dem Zettel und 
habe es auch in mein Programm implementiert, kurz bevor Jens mit seiner 
Idee um die Ecke kam.

Läuft.

Wobei ich mysql_sqlstate() vom Ansatz her interessanter finde, weil ich 
so einmal die Antwort meiner Frage bekommen würde und im Fehlerfall eben 
auch direkt den passenden Fehlercode, der beschreibt, was genau falsch 
gelaufen ist.

Ich werde diesen Ansatz morgen Abend mal in mein Programm einbauen und 
sehen wie es funktioniert.

Danke für die hilfreichen und netten Postings.

von Jens G. (jensig)


Lesenswert?

> Karl Heinz (kbuchegg) (Moderator)

>Allerdings ist ein 0-Ergebnis eines SELECT für mich auch kein Error. Es
>ist ein ganz normales Ergebnis, das bei einer Datenbankabfrage vorkommen
>kann und wird auch als solches behandelt: Als ganz normales Ergebnis und
>nicht als Error.

>Wenn man die Anzahl wissen will, dann kann man immer noch einen COUNT
>benutzen und kein SELECT. Aber abholen muss man das Ergebnis da wie
>dort. Weder ein leeres SELECT-Ergebnis noch ein COUNT-Ergebnis von 0 ist
>da ein Fehler. Und ich seh da ehrlich gesagt auch nicht ein, warum das
>ein Fehler sein sollte. Wenn ich etwas suche, dann muss ich immer damit
>rechnen, dass das Gesuchte nicht gefunden werden kann. Dieser Fall ist
>aber davon zu trennen, dass die Abfrage schon nicht korrekt formuliert
>wurde und deshalb die ganze Abfrage in sich gescheitert ist. Ist die
>Abfrage korrekt formuliert, gab es auch kein sonstiges technisches
>Problem, dann ist ein Ergebnis, das aus 0 Datensätzen besteht, genauso
>ein Ergebnis wie jedes andere auch.

Genau so ist es.

00000 heist einfach erfolgreich, ohne jede Wertaussage.
Eine etwas genauere Aussage wäre 02000 - Erfolgreich (im Sinne von kein 
technischer Error), aber keine Row gefunden (also leeres Resultset).
Wenn man also zw. vorhanden und nicht vorhanden unterscheiden will, muß 
man nur zw. 00000 und 02000 unterscheiden - alles andere wäre Error, 
oder zumindest Warning/Info.

: Bearbeitet durch User
von Jens G. (jensig)


Lesenswert?

Übrigens ist der sqlstate "international genormt". Wer also diesen 
Fehlercode benutzt, ist grundsätzlich schon auf dem 
kompatiblen/portablen Wege ...

von Matthias (Gast)


Lesenswert?

Ich habe jetzt vorlaeufig eine einfache Kombination aus 
Validitaetspruefung mittels mysql_error() -wg. des ordentlichen 
Fehlerstrings- und inhaltlicher Pruefung durch mysql_store_result i.V.m. 
mysql_num_rows() gewaehlt.

Mein Programm ist fertig und laeuft gut. Bevor es soweit kam hatte ich 
aber noch eine Stolperfalle -an die ich nie gedacht haette und auf die 
ich erst durch den Gebrauch einer Suchmaschine und des Apache Error Logs 
gestossen bin-.

Lasse ich free_mysql_result(mysql_result) in meinem CGI-Skript drin, 
zeigt das ErrorLog scheinbar eine Speicherkorruption.

Gemaess Suchmaschine ist das Problem bekannt. In der Dokumentation kein 
Hinweis auf diesbezuegliche Probleme.

Mein Programm laeuft mit nur einem mysql_store_result, insofern kann ich 
es theoretisch, wie praktisch weglassen. Wenn ich aber kuenftig zwei 
mysql_store_results() nacheinander aufrufen moechte muss ich 
mysql_free_result() nutzen.

Kennt noch jemand das Problem und weiss evtl., wie man es beheben kann 
und/oder welche Ursache ueberhaupt dazu fuehrt?

von Jim M. (turboj)


Lesenswert?

Matthias schrieb:
> Kennt noch jemand das Problem und weiss evtl., wie man es beheben kan

Dazu müssten wird Deinen Code kennen, und zwar komplett.

von Matthias (Gast)


Lesenswert?

Das Problem hat sich erledigt nachdem ich einen Post seitens eines mysql 
Entwicklers gelesen habe und daraufhin eine neuere Version installiert 
habe.

>But note that we do not fix bugs in older version anyway, so if 5.0.76 (current 
one) does not have it, then we'd assume it was fixed somehow in the process.

http://bugs.mysql.com/bug.php?id=33807

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.