mySQL und Perl
Markus**
- perl
Folgender code:
$sth=$dbh->prepare($statement);
$sth->execute();
$rows=$sth->rows;
$sth->finish();
return($rows);
sollte die Anzahl der betroffenen Zeilen zurückgeben, nicht wahr? Und die Datenbank sollte da "0" zurückgeben, wenn ich ein "UPDATE" ausführe, was nichts bewirkt. Tut's aber nicht.... es gibt immer mindestens "1" bzw. "-1" (siehe unten) zurück...
man - woran liegt das?
aus der Doku:
$sth->rows
Returns the number of rows affected by the last row affecting command, or -1 if the number of rows is not known or not available.
hi,
Folgender code:
$sth=$dbh->prepare($statement);
$sth->execute();
$rows=$sth->rows;
$sth->finish();
return($rows);sollte die Anzahl der betroffenen Zeilen zurückgeben, nicht wahr? Und die Datenbank sollte da "0" zurückgeben, wenn ich ein "UPDATE" ausführe, was nichts bewirkt. Tut's aber nicht.... es gibt immer mindestens "1" bzw. "-1" (siehe unten) zurück...
man - woran liegt das?
Stimmt Dein Statement, funktioniert das auch außerhalb von Perl?
aus der Doku:
$sth->rows
Returns the number of rows affected by the last row affecting command, or -1 if the number of rows is not known or not available.
Mit rows() hatte ich auch mal Probleme, die ich nicht nachvollziehen konnte. Seitdem benutze ich count(spaltenname);
Viele Grüße,
Hotte
$sth->rows
Returns the number of rows affected by the last row affecting command, or -1 if the number of rows is not known or not available.
Mit rows() hatte ich auch mal Probleme, die ich nicht nachvollziehen konnte. Seitdem benutze ich count(spaltenname);
Bei einem Update?
Struppi.
Stimmt Dein Statement, funktioniert das auch außerhalb von Perl?
aber klar - das hab ich längst probiert!
Mit rows() hatte ich auch mal Probleme, die ich nicht nachvollziehen konnte. Seitdem benutze ich count(spaltenname);
nutzt mir nichts, ich möchte bitte wissen wiviele Datensätze GEÄNDERT wurden. Das kann halt im Zweifel KEINER sein, wenn das UPDATE query IDENTISCHE einträge überschreiben WILL.
thanks und Gruß,
Markus
hi,
$sth=$dbh->prepare($statement);
$sth->execute();
$rows=$sth->rows;
$sth->finish();
return($rows);sollte die Anzahl der betroffenen Zeilen zurückgeben, nicht wahr? Und die Datenbank sollte da "0" zurückgeben, wenn ich ein "UPDATE" ausführe, was nichts bewirkt.
Also ich hab das jetzt mal nachgebaut und es funktioniert so wie Du schreibst mit einer Tabelle vom Typ MyISAM. Evntl. hast Du einen anderen Tabellentyp der ein commit() erfordert.
Viele Grüße,
Horst Haselhuhn
mahlzeit!
Also ich hab das jetzt mal nachgebaut und es funktioniert so wie Du schreibst mit einer Tabelle vom Typ MyISAM. Evntl. hast Du einen anderen Tabellentyp der ein commit() erfordert.
Ich hab MyISQM Tabellen und bekomme "1" zuürck, wenn ich ein UPDATE ausführe was NICHTS ÄNDERT. Ich erwarte allerding die Rückgabe "0".
"-1" kommt zurück, wenn das Ausführen des statements fehlschlägt
und n kommt zurück wenn n datensätze verändert wurden.
Mist! :)
mahlzeit!
Also ich hab das jetzt mal nachgebaut und es funktioniert so wie Du schreibst mit einer Tabelle vom Typ MyISAM. Evntl. hast Du einen anderen Tabellentyp der ein commit() erfordert.
Ich hab MyISQM Tabellen und bekomme "1" zuürck, wenn ich ein UPDATE ausführe was NICHTS ÄNDERT. Ich erwarte allerding die Rückgabe "0".
Da ist irgendwas faul, das muss gehen ;-)
Poste mal DBI::Version; Perl-version, MySQL-Version zum Vergleich.
Btw.,
use strict; # ?
use warnings; # ?
--Hotte
OK!
DBI: 1.602
(Active)Perl: 5.8.0.804
DBD-mysql: 3.0002
mySQL: 5.0.18
OS: Win2k SP4
soweit dazu...
Also: nochmal zur Prüfung: ich erzeuge das statement dynamisch, hab es mir einfach mal als Text ausgeben lassen und im PHPmyAdmin sowie im mySQL Command line probiert. Beide male bekomme ich "affected rows: 0" zurück, nur mein Perlscript gibt "1".
Das darf doch wohl nicht wahr sein! *genervt ist*
genervter Gruß,
Markus
OK!
DBI: 1.602
(Active)Perl: 5.8.0.804
DBD-mysql: 3.0002
mySQL: 5.0.18
OS: Win2k SP4soweit dazu...
Also: nochmal zur Prüfung: ich erzeuge das statement dynamisch, hab es mir einfach mal als Text ausgeben lassen und im PHPmyAdmin sowie im mySQL Command line probiert. Beide male bekomme ich "affected rows: 0" zurück, nur mein Perlscript gibt "1".
Das darf doch wohl nicht wahr sein! *genervt ist*
Hmm,
bei mir tut's. Evntl. ein Bug in den neureren Versionen, anders kann ich mir das jetzt auch nicht erklären.
Viele Grüße,
Hotte
ich hoffe wir reden nicht aneinander vorbei ich hab hier nochmal geschrieben was ich erwarte...
wie sieht den Dein "test-sql-statement" aus?
Gruß, Markus
ich hoffe wir reden nicht aneinander vorbei ich hab hier nochmal geschrieben was ich erwarte...
wie sieht den Dein "test-sql-statement" aus?
genauso wie Deins, ich mache in Update und zähle die affected rows:
use strict;
use lib '/var/www/vhosts/rolfrost.de/cgi-bin';
use DBI;
use Basic;
my $dbh = connMySQL;
my $st = qq(UPDATE spamprot SET zeitstempel = 4);
my $sth=$dbh->prepare($st);
$sth->execute();
my $rows=$sth->rows;
$sth->finish();
print "$rows\n"; # und das stimmt ;-)
--Hotte
genauso wie Deins, ich mache in Update und zähle die affected rows:
use strict;
use lib '/var/www/vhosts/rolfrost.de/cgi-bin';
use DBI;
use Basic;my $dbh = connMySQL;
my $st = qq(UPDATE spamprot SET zeitstempel = 4);
my $sth=$dbh->prepare($st);
$sth->execute();
my $rows=$sth->rows;
$sth->finish();print "$rows\n"; # und das stimmt ;-)
und zurück kommt in dem Fall "1" :-) oder irre ich mich?
genauso wie Deins, ich mache in Update und zähle die affected rows:
use strict;
use lib '/var/www/vhosts/rolfrost.de/cgi-bin';
use DBI;
use Basic;my $dbh = connMySQL;
my $st = qq(UPDATE spamprot SET zeitstempel = 4);
my $sth=$dbh->prepare($st);
$sth->execute();
my $rows=$sth->rows;
$sth->finish();print "$rows\n"; # und das stimmt ;-)
und zurück kommt in dem Fall "1" :-) oder irre ich mich?
Zum Verständis (was wir beide haben):
Die Spalte zeitstempel bekommt ein update auf 4. Da keine whereKlause drin ist, werden alle records das Update bekommen, das sind bei mir 3 records und die 3 steht dann in $rows. In einem zweiten Durchlauf ist $rows == 0, weil sich per update keine Änderung ergab.
Mache ich einen dritten Durchlauf mit
my $st = qq(UPDATE spamprot SET zeitstempel = 5);
zeigt mir $rows wiederum, dass 3 rows vom update betroffen sind.
Schade, dass das bei Dir nicht so tut, aber wie gesagt, ich vermute einen oder mehrere Bugs. Schraub Dich mal durch CPAN und die Repository vom DBI.pm, vielleicht wirst Du da fündig.
Evntl. ist auch
use strict;
use warnings;
im PerlCode hilfreich, nicht dass da der Hase im Pfeffer liegt.
--Hotte
Schade, dass das bei Dir nicht so tut, aber wie gesagt, ich vermute einen oder mehrere Bugs. Schraub Dich mal durch CPAN und die Repository vom DBI.pm, vielleicht wirst Du da fündig.
Du solltest ein bisschen mitlesen. er will Wissen ob etwas geändert wurde, nicht wieviel.
Struppi.
er will Wissen ob etwas geändert wurde, nicht wieviel.
trifft's exakt!
hi,
Schade, dass das bei Dir nicht so tut, aber wie gesagt, ich vermute einen oder mehrere Bugs. Schraub Dich mal durch CPAN und die Repository vom DBI.pm, vielleicht wirst Du da fündig.
Du solltest ein bisschen mitlesen. er will Wissen ob etwas geändert wurde, nicht wieviel.
Na Du bist villeicht ein IT-Experte ;-)
Schau mal, so einfach gehts mit einer Kontrollstruktur in Perl:
if( $sth->rows == 0 ){ # nichts wurde geändert }
elsif( $sth->rows == -1 ){ # das Statement ging schief }
else{ # es wurde was geändert }
Viele Grüße,
Horst
Na Du bist villeicht ein IT-Experte ;-)
Im gegensatz zu dir hab ich aber verstanden worum es Markus geht.
Schau mal, so einfach gehts mit einer Kontrollstruktur in Perl:
Das löst nach wie vor nicht das Problem von Markus
Struppi.
Schade, dass das bei Dir nicht so tut, aber wie gesagt, ich vermute einen oder mehrere Bugs. Schraub Dich mal durch CPAN und die Repository vom DBI.pm, vielleicht wirst Du da fündig.
Mist, werd' ich wohl tun müssen :-/ Mannoooo! Das kann doch nicht sein, dass das vor mir noch keiner gemerkt hat! :/
Mist, werd' ich wohl tun müssen :-/ Mannoooo! Das kann doch nicht sein, dass das vor mir noch keiner gemerkt hat! :/
Ich mach solche Prüfungen in meiner Anwendung. Oft macht man ja einen update auf einen Datensatz, den man vorher bearbeitet.
Struppi.
Schade, dass das bei Dir nicht so tut, aber wie gesagt, ich vermute einen oder mehrere Bugs. Schraub Dich mal durch CPAN und die Repository vom DBI.pm, vielleicht wirst Du da fündig.
Mist, werd' ich wohl tun müssen :-/ Mannoooo! Das kann doch nicht sein, dass das vor mir noch keiner gemerkt hat! :/
Ich gebe zu, dass mir die DBI-Funktion rows() auch erst heute so richtig klar geworden ist im Dialog mit Dir und mit einem eigens dazu gebauten Script.
Warum das bei Dir nicht tut, keine Ahnung. Möglicherweise Bug.
Viele Grüße,
Hotte
my $sth=$dbh->prepare($st);
$sth->execute();
my $rows=$sth->rows;
Das ist nicht notwendig, execute gibt die Anzahl der Reihen bereits zurück.
http://search.cpan.org/~timb/DBI/DBI.pm#execute
For a non-SELECT statement, execute returns the number of rows affected, if known. If no rows were affected, then execute returns "0E0", which Perl will treat as 0 but will regard as true. Note that it is not an error for no rows to be affected by a statement. If the number of rows affected is not known, then execute returns -1.
Struppi.
my $sth=$dbh->prepare($st);
$sth->execute();
my $rows=$sth->rows;Das ist nicht notwendig, execute gibt die Anzahl der Reihen bereits zurück.
genau das hab ich auch schon festgestellt, trotzdem komm ich nicht an mein gewünschte Ziel ohne mittels SELECT zu prüfen ob eine Änderung vorgenommen wurde oder nicht! :-/ sehr unschön!
Gruß, Markus
my $sth=$dbh->prepare($st);
$sth->execute();
my $rows=$sth->rows;Das ist nicht notwendig, execute gibt die Anzahl der Reihen bereits zurück.
genau das hab ich auch schon festgestellt, trotzdem komm ich nicht an mein gewünschte Ziel ohne mittels SELECT zu prüfen ob eine Änderung vorgenommen wurde oder nicht! :-/ sehr unschön!
Ich weiß das bereits und mir ist keine Lösung bekannt.
Mir ging es nur um den Code von Rolf/Hotte/Hotti der den unnötigen Aufruf enthält.
Struppi.
Vielleicht sollte ich nochmal in einfachen Worten mein Ziel beschreiben! ;)
Ich möchte feststellen ob ein "UPDATE table_name SET y = 'wert'" den Datenbestand verändert oder nicht.
Gruß, Markus
Vielleicht sollte ich nochmal in einfachen Worten mein Ziel beschreiben! ;)
Ich möchte feststellen ob ein "UPDATE table_name SET y = 'wert'" den Datenbestand verändert oder nicht.
In dem Fall, gibt der Update Befehl ein 0E0 zurück.
Struppi.
In dem Fall, gibt der Update Befehl ein 0E0 zurück.
Das hab ich auch der Doku entnommen, bei mir kommt aber "1" zurück - warum zur Hölle? :)
In dem Fall, gibt der Update Befehl ein 0E0 zurück.
Das hab ich auch der Doku entnommen, bei mir kommt aber "1" zurück - warum zur Hölle? :)
Dann machst du etwas falsch oder bei dir stimmt etwas nicht, bei mir kommt 0E0 zurück, wenn UPDATE nichts macht.
Struppi.
Dann machst du etwas falsch oder bei dir stimmt etwas nicht, bei mir kommt 0E0 zurück, wenn UPDATE nichts macht.
Okay... hier mal mein Testcode:
$statement = qq{
UPDATE bus_vehicle
SET
driver_name = 'Marcel Jansen',
driver2_name = 'Jogi Löw',
driver_cell = '123456767',
driver2_cell = '784357989',
driver_email = 'm.jansen@nationalmannschaft.de',
driver2_email = 'jogi@nationalmannschaft.de',
parking = 'outside',
passenger = '026',
bus_sign = 'ab-cd 123',
countrycode = '49',
countrycode2 = '49',
time_id = '21'
WHERE bus_id = '212'};
print query($statement);
print query($statement);
sub query
{
$sth=$dbh->prepare($_[0]);
$sth->execute();
$rows=$sth->rows;
$sth->finish();
return($rows);
exit;
}
Folgendes gibt 2x 1 aus - obwohl ja spätestens bei der zweiten print Anweisung 0 bzw. auch 0E0 zurück kommen sollte, oder? Hab ich heute eigentlich irgendwas völlig verrafft?
Gruß, Markus
Folgendes gibt 2x 1 aus - obwohl ja spätestens bei der zweiten print Anweisung 0 bzw. auch 0E0 zurück kommen sollte, oder? Hab ich heute eigentlich irgendwas völlig verrafft?
Ach jetzt wird dein Problem klar. Soweit ich das sehe, kannst du nicht festellen ob der update überflüssig ist. Obwohl mysql diese Information bereit stellt, ich weiß aber nicht ob und wo DBI dieses Angaben abfragt.
Struppi.
Ach jetzt wird dein Problem klar. Soweit ich das sehe, kannst du nicht festellen ob der update überflüssig ist. Obwohl mysql diese Information bereit stellt, ich weiß aber nicht ob und wo DBI dieses Angaben abfragt.
Struppi.
Aha... da haben wir es doch! ;) Soll das heißen dass ich das also händisch prüfen muß? Arghl! Ich will doch nich vorm UPDATE ein SELECT durchführen um die Daten gegen zu prüfen... das ist ja... nein, das ist das was ich eigentlich NICHT will. Aber offenbar bleibt mir ja nichts anderes übrig :-/
Oder hat jemand ne patentere Idee? Ich lese derweil nochmal die DBI perldoc.
Gruß, Markus
Oder hat jemand ne patentere Idee? Ich lese derweil nochmal die DBI perldoc.
Für UPDATEs wird generell do empfohlen, wie sieht es dann bei Dir aus? Ansonsten sagt die Dokumentation:
"For a non-SELECT statement, execute returns the number of rows affected, if known. If no rows were affected, then execute returns "0E0", which Perl will treat as 0 but will regard as true. Note that it is not an error for no rows to be affected by a statement. If the number of rows affected is not known, then execute returns -1."
Mach also mal spaßeshalber
$rows = $sth->execute;
Siechfred
Für UPDATEs wird generell do empfohlen, wie sieht es dann bei Dir aus?
Mach also mal spaßeshalber
$rows = $sth->execute;
ja, dann kommt 1 zurück, auch wenn nichts geänder wird - darum geht's ja die ganze Zeit! :-) Same shit wenn ich do() benutze. Also?
Gruß, Markus
In dem Fall, gibt der Update Befehl ein 0E0 zurück.
Das hab ich auch der Doku entnommen, bei mir kommt aber "1" zurück - warum zur Hölle? :)
Ach, ich meine die do() Funktion nicht rows
Struppi.
Erstmal einen Dank an Euch auf für die Hilfe!
Ich fand folgenden Eintrag in einer Newsgroup, der die Problematik und eine Lösung schildert. Es ist ein konfigurations-problem!
-----------------------------------------
Hmmm, I forgot about this outstanding issue. This is a known behaviour
of the MySQL engine, call it a bug or a feature, as you like. (It declares
"affected" as "changed".) The behaviour you are expecting can be enabled
by setting the C flag CLIENT_FOUND_ROWS when connecting to the database.
I have now uploaded a version 1.2205 of the Msql-Mysql-modules to CPAN
which has the following new feature: When connecting with
DBI->connect("DBI:mysql:test;mysql_client_found_rows=0", ...)
then you have the old behaviour. With
DBI->connect("DBI:mysql:test;mysql_client_found_rows=1", ...)
you have CLIENT_FOUND_ROWS set, thus your query will always return 1.
The default is 0, however you can change this by compiling the
Msql-Mysql-modules with
perl Makefile.PL --config --mysql-use-client-found-rows
in which case the default is 1.
Monty, I dislike that this must be choosen while connecting to the
client. Couldn't we make this part of the MYSQL structure?
-----------------------------------------
Quelle: http://lists.mysql.com/perl/250?f=plain
Gruß, Markus
Lange und gut gesucht, vermute ich mal ;-)
Monty, I dislike that this must be choosen while connecting to the
client. Couldn't we make this part of the MYSQL structure?
Das haben sie wohl umgesetzt.
Die Frage ist, wenn du das in der mySql Konsole machst erhälst du tasächlich zwei Werte, rows und changed, bei einer Änderung wo nichts passiert, ist rows 1 und changed 0, d.h. mysql gibt eigentlich diese Information preis, warum bekommt das Modul das nicht.
Struppi.
Lange und gut gesucht, vermute ich mal ;-)
Die Frage ist, wenn du das in der mySql Konsole machst erhälst du tasächlich zwei Werte, rows und changed, bei einer Änderung wo nichts passiert, ist rows 1 und changed 0, d.h. mysql gibt eigentlich diese Information preis, warum bekommt das Modul das nicht.
Jo. Hab allerdings nach der Diskussion hier, ziemlich genau gewusst was nach was ich bei google suchen muß! ;) "CPAN DBI mySQL BUG affected rows" hat mir das gewünschte Resultat gebracht.
Denke das Modul bzw. der treiber bekommt die Werte, allerdings werden sie nicht _BEIDE_ weiterverarbeitet, bzw. man muß definieren welchen man "sehen" möchte.
Who knows?!
Gruß´, Markus