1 2 3 4 5 6 7 8 9 10
use DBI; my $dbh = DBI->connect("dbi:SQLite:dbname=test.db","","") or die DBI::errstr; my $sql = "SELECT ID, Vegetarisch FROM Buchungen WHERE Datum = '".datum()."';"; my $sth = $dbh->prepare($sql); $sth->execute; my $anzahl_rows = $sth->rows; print $anzahl_rows;
QuoteGenerally, you can only rely on a row count after a non-SELECT execute (for some specific operations like UPDATE and DELETE), or after fetching all the rows of a SELECT statement.
For SELECT statements, it is generally not possible to know how many rows will be returned except by fetching them all. Some drivers will return the number of rows the application has fetched so far, but others may return -1 until all rows have been fetched. So use of the rows method or $DBI::rows with SELECT statements is not recommended.
2011-05-09T07:39:25 GwenDragonSo wie ich das sehe, muss du erst mal alle Zeilen holen, bevor rows einen korrekten Wert hat.
1 2
my $sql = "SELECT count(*) FROM Buchungen WHERE Datum = '".datum()."';"; # usw.
1 2 3 4 5
my $sql = "SELECT COUNT(*) FROM Buchungen WHERE Datum = '".$datum."';"; my $sth = $dbh->prepare($sql); $sth->execute; my $rows_count = $sth->fetchrow;
2011-05-09T07:16:33 KeanWenn ich über DBI aus einer SQLite Datenbank Daten abfrage und nach dem Execute ...
1 2 3 4 5 6
my $dsn = "DBI:mysql:database=$cfg->{mysql}->{base};host=$cfg->{mysql}->{host};port=$cfg->{mysql}->{port}"; eval{ $self->{DBH} = DBI->connect_cached( $dsn, $cfg->{mysql}->{user}, $cfg->{mysql}->{pass}, {RaiseError => 1, PrintError => 0} ); };
1 2 3 4 5 6 7
eval{ my $sth = $self->{DBH}->prepare_cached($ref->{query}); $self->{SCALAR} = $sth->execute; $self->{CB} = $ref->{CB}; $self->{STH} = $sth; }; return if $@;
2011-05-09T07:43:30 rostiCode (perl): (dl )1 2 3 4 5 6my $dsn = "DBI:mysql:database=$cfg->{mysql}->{base};host=$cfg->{mysql}->{host};port=$cfg->{mysql}->{port}"; eval{ $self->{DBH} = DBI->connect_cached( $dsn, $cfg->{mysql}->{user}, $cfg->{mysql}->{pass}, {RaiseError => 1, PrintError => 0} ); };
Wobei das übrigens die einzige Möglichkeit ist, über $@ (EVAL_ERROR) zu erfahren, warum der connect schief geht.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
use strict; use warnings; use DBI; my $dsn = "DBI:mysql:database=testdb;host=localhost;port=3306"; my $dbh; eval{ $dbh = DBI->connect_cached( $dsn, "root", "", {RaiseError => 1, PrintError => 0} ); }; eval{ my $sth = $dbh->prepare_cached("SELECT * FROM testtable"); $self->{SCALAR} = $sth->execute; # --> ? $self->{CB} = $ref->{CB}; # --> ? $self->{STH} = $sth; # --> ? }; return if $@;
1 2 3 4 5 6 7 8 9 10
if(tie my $status, 'SQL', {query => $sql-zeugs, CB => \&callback}){ # Ok, wir können $status abfragen und die Callbackfunktion rufen tied($status)->cb_array; # Method in Class 'SQL' # in cb_array{} wird vermittels {STH} über das Resultat iteriert # und jede Zeile als Array-Referenz an die Callback-Funktion {CB} gegeben } else{ # Nein, es gab einen Fehler, wir fragen $@ }
1 2 3 4 5 6 7 8 9 10 11 12
#!/usr/bin/perl use strict; use warnings; use myDB; my $db=myDB->new(); die($db->error()) if($db->error()); my @data=$db->fetch_all(); warn($db->error()) if($db->error()); #...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
package Unicode; use myConfig qw($cfg); use strict; use DBI; # Konstruktor, DB-Connect sub new{ my $class = shift; my $self = { DBH => undef, }; bless $self, $class; my $dsn = "DBI:mysql:database=$cfg->{mysql}->{base};host=$cfg->{mysql}->{host};port=$cfg->{mysql}->{port}"; eval{ $self->{DBH} = DBI->connect_cached( $dsn, $cfg->{mysql}->{user}, $cfg->{mysql}->{pass}, {RaiseError => 1, PrintError => 0} ); }; return $self; } # hier wird nur das Objekt zurückgegeben sub TIEHASH{ my $class = shift; my $self = $class->new; if($@){ return } else{ return $self} } # erst hier werden die Daten aus der mySQL-Tabelle geholt sub FETCH{ my $self = shift; my $key = shift; # Codepoint decimal, cpd my $q = q(SELECT cpd, name FROM unicode WHERE cpd=?); my $href = {}; eval{ my $sth = $self->{DBH}->prepare($q); $sth->execute($key); $href = $sth->fetchall_hashref('cpd'); }; if($@){ return "Fehler: $@" } else{ return $href->{$key}->{name} } } 1;######################################################################### package main; tie(my %h, 'Unicode') or die $@; print $h{8364}; # EURO SIGN
1 2
my $sth = $dbh->prepare($sql) or die $dbh->errstr; $sth->execute or die $dbh->errstr;
2011-05-09T08:33:42 GwenDragonEs ist sinnvoll, alle aufgerufenen Datenbankfunktionen auf Fehlschläge zu überprüfen und dann $DBI::errstr bzw. der Methode errstr() die Fehlermeldung auszugeben.
Weder bei prepare noch execute prüfst du.
Code (perl): (dl )1 2my $sth = $dbh->prepare($sql) or die $dbh->errstr; $sth->execute or die $dbh->errstr;
$sth->execute or die $dbh->errstr;
QuoteAn undef is returned if an error occurs. A successful execute always returns true regardless of the number of rows affected, even if it's zero (see below).
It is always important to check the return status of execute (and most other DBI methods) for errors if you're not using "RaiseError".
1
2
3
4
$ perl -wle 'sub foo { return undef; } foo or die "tot"'
tot at -e line 1.
$ perl -wle 'sub foo { return 0; } foo or die "tot"'
tot at -e line 1.
perldoc DBIFor 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.
QuoteA successful execute always returns true regardless of the number of rows affected, even if it's zero (see below).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my $sth = $dbh->prepare($sql);
if( $sth ) {
# prepare hat geklappt, jetzt kannst du execute() aufrufen.
}else{
# prepare hat nicht geklappt, behandle den Fehler
#die('Crash to Desktop');
require Tk::Dialog;
my $error_dialog = $mw->Dialog(
-title => 'Kann Daten nciht aus DB auslesen',
-text => 'Fehler: ' . $dbh->errstr(),
# ....
);
my $selected = $error_dialog->Show();
}