Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]583[/thread]

Wieso läuft dieses Skript unendlich lange?!



<< |< 1 2 >| >> 19 Einträge, 2 Seiten
Gast Gast
 2005-09-27 11:34
#5690 #5690
Problem:

Siehe Titel

Was ich eigentlich wollte:

Ich wollte eine Funktion schreiben, die ein Select aus einer Datenbank noch etwas vereinfacht. Wenn ich mein Beispiel hier ohne meine Funktion ausführe dann funktionierts.. Aber irgend wie happerts wohl mit dem return $sth->fetchrow_hashref();
Die SQL-Abfrage funktioniert so weit eigentlich. Aber wenn ich sie nachher mit der while-Schleife ausgeben will wiederholt sich der erste Eintrag unendlich viel mal, weil er nicht kappiert, dass er zum nächsten Eintrag springen soll.
Ist es generell nicht möglich hashrefs aus einer Funktion heraus zu geben oder wo liegt das Problem?? Danke für die Hilfe ...

-----------------------------------------------------------------------------------
Code: (dl )
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
#!/usr/bin/perl -w
use CGI::Carp qw(fatalsToBrowser);
use DBI;

#Variabeln Deklarierung
$dbname="cdliste";
$username="root";
$pw="123";
$db = "DBI:mysql:$dbname";

#Die Verbindung zur Datenbank wird hergestellt
$dbh = DBI->connect($db, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");

sub selecthashref ($){

$sth = $dbh->prepare( $_[0] ) or return "$DBI::err: $DBI::errstr";
$sth->execute();
return $sth->fetchrow_hashref();

};

#Legt den Dokumenttypen fest
print "Content-type: text/html; charset=iso-8859-1\n\n";

while ($row_ref = selecthashref("SELECT * FROM ordner ORDER BY ordnername ASC")){

print "$row_ref->{ordnerid}\n";
}

-----------------------------------------------------------------------------------


edit renee: ne Runde [code]-Tags spendiert\n\n

<!--EDIT|renee|1127806616-->
renee
 2005-09-27 11:39
#5691 #5691
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Du verlangst immer die erste Zeile. Du setzt immer wieder das Statement neu ab. Und da das immer die erste Zeile zurückliefert läuft es endlos...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2005-09-27 11:45
#5692 #5692
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Du solltest Dir auch mal Wiki:use strict anschauen...

So könnte es klappen...
Code: (dl )
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
#!/usr/bin/perl

use strict;
use warnings;
use CGI::Carp qw(fatalsToBrowser);
use DBI;

#Variabeln Deklarierung
my $dbname="cdliste";
my $username="root";
my $pw="123";
my $db = "DBI:mysql:$dbname";

#Die Verbindung zur Datenbank wird hergestellt
my $dbh = DBI->connect($db, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");

sub selecthashref{
my ($statement,@array) = @_;;
unless(my $sth = $dbh->prepare( $statement)){
die $dbh->err().": ".$dbh->errstr();
}
$sth->execute() or die $dbh->errstr();
while(my $hashref = $sth->fetchrow_hashref()){
push(@array,$hashref);
}
return \@array;
}

#Legt den Dokumenttypen fest
print "Content-type: text/html; charset=iso-8859-1\n\n";

foreach my $row_ref(@{selecthashref("SELECT * FROM ordner ORDER BY ordnername ASC")}){
print "$row_ref->{ordnerid}\n";
}


edit Relais: Wiki-Link repariert\n\n

<!--EDIT|Relais|1127812310-->
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
raprezent
 2005-09-27 11:53
#5693 #5693
User since
2005-09-27
12 Artikel
BenutzerIn
[default_avatar]
ja von dem bin ich ausgegangen, dass er den zeiger immer an den anfang setzt :) ... aber mal grob gesagt ich kann nur ein array aus der funktion ausgeben und kein hashref??

ich probiere jetzt mal das was du mir da zusammen gecodet hast :) . . auf jedenfall schon mal danke
renee
 2005-09-27 12:02
#5694 #5694
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Man kann "alles" zurückgeben. Aber ich denke, dass Du alle selektierte Einträge haben willst. Damit Du alle Einträge bekommst, schiebe ich die in ein Array...

Mal als Erklärung, warum Dein Skript endlos lief:

Stelle Datenbankverbindung her
selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

selektiere Alles aus Tabelle aufsteigend sortiert, liefere die erste Zeile (while-Bedingung ist true)
gebe die Id aus

[... und so weiter ...]


Ich nehme an, Dein ursprünglicher Gedanke war, das Statement einmal auszuführen und dann immer auf den nächsten Eintrag zu zeigen und auszugeben. Du rufst aber bei jedem Schleifendurchlauf die Methode auf, in der jedesmal das Statement erneut ausgeführt wird...

Eine andere Möglichkeit wäre:
Code: (dl )
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
#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);
use DBI;

#Variabeln Deklarierung
my $dbname="cdliste";
my $username="root";
my $pw="123";
my $db = "DBI:mysql:$dbname";

#Die Verbindung zur Datenbank wird hergestellt
my $dbh = DBI->connect($db, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");

sub selecthashref ($){
my $sth = $dbh->prepare( $_[0] ) or return "$DBI::err: $DBI::errstr";
$sth->execute() or die $dbh->errstr();
return $sth;
};

#Legt den Dokumenttypen fest
print "Content-type: text/html; charset=iso-8859-1\n\n";

my $sth = selecthashref("SELECT * FROM ordner ORDER BY ordnername ASC");
while ($row_ref = $sth->fetchrow_hashref()){
print "$row_ref->{ordnerid}\n";
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
raprezent
 2005-09-27 12:02
#5695 #5695
User since
2005-09-27
12 Artikel
BenutzerIn
[default_avatar]
kannst du mir bitte die einzelnen Zeilen etwas erklären??
ich bin immer noch am perl lernen ...

sub selecthashref{
my ($statement,@array) = @_;
unless(my $sth = $dbh->prepare( $statement)){
die $dbh->err().": ".$dbh->errstr();
}
$sth->execute() or die $dbh->errstr();
while(my $hashref = $sth->fetchrow_hashref()){
push(@array,$hashref);
}

return \@array;
}

#Legt den Dokumenttypen fest
print "Content-type: text/html; charset=iso-8859-1\n\n";

foreach my $row_ref(@{selecthashref("SELECT * FROM ordner ORDER BY ordnername ASC")}){
print "$row_ref->{ordnerid}\n";
}
raprezent
 2005-09-27 12:07
#5696 #5696
User since
2005-09-27
12 Artikel
BenutzerIn
[default_avatar]
Ja ok das habe ich eigentlich schon verstanden .. ich könnte ja also rein theoretisch den code etwas abändern dass das nicht mehr passieren sollte

Code: (dl )
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
#!/usr/bin/perl -w
use CGI::Carp qw(fatalsToBrowser);
use DBI;

#Variabeln Deklarierung
$dbname="cdliste";
$username="root";
$pw="123";
$db = "DBI:mysql:$dbname";

#Die Verbindung zur Datenbank wird hergestellt
$dbh = DBI->connect($db, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");




sub selecthashref ($){

$sth = $dbh->prepare( $_[0] ) or return "$DBI::err: $DBI::errstr";
$sth->execute();
return $sth->fetchrow_hashref();

};


#Legt den Dokumenttypen fest
print "Content-type: text/html; charset=iso-8859-1\n\n";
[b]
$row_ref = selecthashref("SELECT * FROM ordner ORDER BY ordnername ASC");
while ($row_ref){[/b]

print "$row_ref->{ordnerid}\n";
}


edit renee: ne Runde [code]-Tags spendiert\n\n

<!--EDIT|renee|1127808794-->
renee
 2005-09-27 12:11
#5697 #5697
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
in @_ stehen die Parameter, die an die Methode übergeben werden. Die Elemente aus dem speziellen Array (siehe Wiki:perldoc perlvar) werden in die Liste ($statement,@array gespeichert. Dadurch landet Dein SELECT-Statement in $statement.
Du hast in Deinem Skript mit $_[0] auf das erste Element von @_ zugegriffen.

Code: (dl )
1
2
3
while(my $hashref = $sth->fetchrow_hashref()){
push(@array,$hashref);
}


solange das fetchrow_hashref() mir eine Hashreferenz zurückliefert, also solange Einträge selektiert wurden, schiebe die Hashreferenz in das Array (siehe perldoc -f push).

@{...} dereferenziert eine Arrayreferenz. Ich habe in der Methode eine Referenz auf ein Array zurückgeliefert. Damit ich auf die einzelnen Elemente zugreifen kann, muss ich erst dereferenzieren. Zu Referenzen lesenswert: Wiki:perldoc perlrefut (ist in Deutsch).

Ein nützliches Modul zum Betrachten von solchen Datenstrukturen ist CPAN:Data::Dumper. Du kannst Dir ja mal zum Spaß die Referenz ausgeben lassen mit:
Code: (dl )
1
2
3
4
use Data::Dumper;

my $arref = selecthashref("SELECT * FROM ordner ORDER BY ordnername ASC");
print Dumper($arref);


Da kannst Du Dir mal anschauen, was in $arref alles drinsteckt...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2005-09-27 12:12
#5698 #5698
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Bitte benute die [code]-Tags!
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
raprezent
 2005-09-27 12:15
#5699 #5699
User since
2005-09-27
12 Artikel
BenutzerIn
[default_avatar]
[quote=renee,27.09.2005, 10:12]Bitte benute die [code]-Tags![/quote]
Ich habe sie absichtlich nicht benutz dass ich text fett anzeigen lassen kann .. dass du gleich siehst was ich geändert habe ..
<< |< 1 2 >| >> 19 Einträge, 2 Seiten



View all threads created 2005-09-27 11:34.