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

DBI-Problem:MySQL-Verbindung bricht automatisch ab



<< |< 1 2 >| >> 13 Einträge, 2 Seiten
Gast Gast
 2004-04-12 04:26
#32011 #32011
Hallo Leute,

vielleicht könnt ihr mir bei folgendem Problem helfen.

Über Perl/DBI greife ich auf eine MySQl Datenbank zu. Das Script, welches die Datenbankanfragen entgegennimmt ist Query.pl, alles klappt soweit. Nun möchte ich, dass die Anmeldung bei der DB, also die Eingabe von MySQL Account und Passwort durch ein separates HTML-Formular (Anmeldung.html) und zugehöriges Perlscript (Anmeldung.pl) erfolgt. Ist die Anmeldung erfolgreich,
so werden die User durch Anmeldung.pl auf die Anfrageseite Query.html umgeleitet.

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
#Das Script ANMELDUNG.PL
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use DBI;

$port = "3306";

read (STDIN, $query_string, $ENV{'CONTENT_LENGTH'});

@Query_keys_values = split(/&/, $query_string);

foreach $key(@Query_keys_values){
chomp ($key);
($Query_key, $Query_value) = split(/=/, $key);
$DB{$Query_key} = $Query_value;
}

$dbh = DBI->connect("DBI:mysql:database=$DB{'DB_name'};host=$DB{'DB_host'}:$port", "$DB{'DB_user'}", "$DB{'DB_password'}");

if (defined ($DBI::err)){
print "Location: Fehlermeldung_Passwort.html","\n\n";
} else {
print "Location: Query.html","\n\n";
}


In dem Code von Anmeldung.pl, seht ihr, dass ich weder die Methode "disconnect" oder das obligatorische "exit" am Ende des Scripts aufrufe - Sinn des Ganzen: die einmal hergestellte DB-Verbindung soll aufrecht erhalten bleiben (für die darauf folgenden Anfragen durch Query.html), und genau das kriege ich trotdem nicht hin. Ich muss mich durch Account und Passwort bei der DB erneut anmelden, d.h. auch Query.pl führt dasselbe $dbh = DBI->connect(...) durch und erst dann erfolgt ein $sth = dbh->do(...) ohne die Fehlermeldung

"Can't call method "do" on an undefined value at Query.pl line ...".

Wenn ich einfach die Zeile mit $dbh = DBI->connect(...) in Query.pl auskommentiere kommt eben diese Fehlermeldung, d.h. das Objekt $dbh von Anmeldung.pl steht für Query.pl nicht mehr zur Verfügung.

Meine Frage also: Wie schaffe ich's, dass die bei der Anmeldung hergestelle DB-Verbindung nicht abbricht und für andere Perl-Scripte ohne Neuanmeldung zur Verfügung steht?

Die Möglichkeit, Account und Passwort, die bei der Anmeldung
eingegeben werden in einer Datei abzuspeichern, und so allen Scripten zur Verfügung zu stellen, möchte ich umgehen. Muss ich vielleicht beim Apache oder bei der MySQL DB irgendwelche Konfigurationen vornehmen? Habe mal ein wenig rumgelesen und denke, dass das Problem folgende Ursache hat: Nachdem ein Perlscript ausgeführt wurde bzw. wenn man die DB-Verbindung nicht explizit durch ein "disconnect" wieder trennt, macht sich der
"Perl Garbage Collector" über nicht mehr benötigte Objekte, bei mir also $dbh her. Im Falle eines DB-Handles wird die "Destroy"-Methode aufgerufen, die wiederum durch den Aufruf von "disconnect" die DB-Verbindung "ohne mein Einverständnis" trennt.
Kann man das verhindern?

2 Tage Suche in diversen Diskussionsgruppen, googlen und seitenweises Lesen haben nichts brauchbares zur Problemlösung gebracht und lassen verzweifeln ;) .

Vielen Dank für eure Hilfe im Voraus.
Dieter
pktm
 2004-04-12 04:42
#32012 #32012
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Naja, die Probleme könnten daraus resultieren, dass du hier und da mal falsch quotest, Semikolon mit den Parametern für DBH übergibst usw.
Auf jeden Fall solltest du dashier benutzen:
use strict;
use warnings;
use diagnostics;

Und dann um es dir ein bischen einfacher zu machen:
use vars;
my $cgi = CGI->new();
my $query = $cgi->Vars(); # Name-Wert-Paare ausm Query in eine Hashreferenz stecken (kann auch als Hash angesprochen werden, siehe perldoc)

Dann wäre da noch die Sachen, dass du die Fehler die beim erzeugen des DBH auftreten könnten nicht abfängst mit my $dbh = DBI->connect( ... ) or print STDERR ("Error in connecting to $query->{DB_name}\n", die => 1); # immer Returncodes und Fehler auswerten!!!

Wenn du dein Datenbankhandle endlich hast kannst du auch genz bequem mit $dbh->err() auf Fehler und auf $dbh->errstr() auf die Fehler im einzelnen zugrefein.
Da fällt mir auf, hast du DBD::MySQL überhaupt geladen?
Dann übergibst du keine Attribute an das DBH, uss allerdings auch nicht sein.
Hoffe das bringt dich weiter.
mfg pktm
http://www.intergastro-service.de (mein erstes CMS :) )
esskar
 2004-04-12 05:02
#32013 #32013
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
hi Dieter;

was du mit deiner Idee vorhast, ist nicht möglich...

Wie du schon schön erklärt hast, wird beim Beenden des anmelde-scripts die verbindung geschlossen und $dbh gelöscht...

die Idee, user und passwort in einer separten datei auf zu bewahren ist wohl die einzige vorgehnensweise, die dir übrig bleibt...
oder du speicherst die daten in Cookies (würde die daten dann aber verschlüsseln) ab...

N8!
Strat
 2004-04-12 13:35
#32014 #32014
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
und ersetze die folgenden zeilen:
[quote=Guest,12.04.2004, 02:26]
Code: (dl )
1
2
3
4
5
6
7
8
9
read (STDIN, $query_string, $ENV{'CONTENT_LENGTH'});

@Query_keys_values = split(/&/, $query_string);

foreach $key(@Query_keys_values){
   chomp ($key);
  ($Query_key, $Query_value) = split(/=/, $key);
   $DB{$Query_key} = $Query_value;
}
[/quote]
durch
Code: (dl )
1
2
my $cgi = CGI->new();
my %DB = $cgi->Vars();

dann laesst sich dein script nicht mehr so einfach aushebeln...
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
DieterW
 2004-04-14 02:53
#32015 #32015
User since
2004-04-14
5 Artikel
BenutzerIn
[default_avatar]
Naja, die Probleme könnten daraus resultieren, dass du hier und da mal falsch quotest, Semikolon mit den Parametern für DBH übergibst usw.
-----------
Stimmt, sieht irgendwie heftig aus. Die Über-Quotierung resultierte u.a. daraus, dass für das Passwort unbedingt "$DB{'DB_password'}" gesetzt werden musste. Wenn ich die beiden "" beim "$DB{'DB_password'}" weggelassen habe funktionierte es nicht mehr. Habe das Ganze nun wie vorgeschlagen vereinfacht, Danke.


Dann wäre da noch die Sachen, dass du die Fehler die beim erzeugen des DBH auftreten könnten nicht abfängst mit my $dbh = DBI->connect( ... ) or print STDERR ("Error in connecting to $query->{DB_name}\n", die => 1); # immer Returncodes und Fehler auswerten!!!
-----------
Also das Abfangen des Fehlers habe ich in die untere if-Anweisung gesteckt, weil ich die "print Location.." -Anweisung in der $dbh-Zeile nicht zum Laufen gekriegt habe. Vorher hatte ich schon ein "$dbh->connect(..) or die(..) " und die diversen "Error Return"-Möglichkeiten wie $DBI::errstr mal ausprobiert. War bei der Problemlösung nicht aussagekräftig genug.


Da fällt mir auf, hast du DBD::MySQL überhaupt geladen?
-------------
Ja habe ich, s. Anfang der connect()-Anweisung. Ich kann zB. auch SELECT, INSERT-Statements von Query.pl ausführen.

ThanX
-Dieter
DieterW
 2004-04-14 02:56
#32016 #32016
User since
2004-04-14
5 Artikel
BenutzerIn
[default_avatar]
[quote=Strat,12.04.2004, 11:35]und ersetze die folgenden zeilen:
[quote=Guest,12.04.2004, 02:26]
Code: (dl )
1
2
3
4
5
6
7
8
9
read (STDIN, $query_string, $ENV{'CONTENT_LENGTH'});

@Query_keys_values = split(/&/, $query_string);

foreach $key(@Query_keys_values){
chomp ($key);
($Query_key, $Query_value) = split(/=/, $key);
$DB{$Query_key} = $Query_value;
}
[/quote]
durch
Code: (dl )
1
2
my $cgi = CGI->new();
my %DB = $cgi->Vars();

dann laesst sich dein script nicht mehr so einfach aushebeln...[/quote]
---------------------------
Hat leider nichts gebracht,
ThaX
-Dieter
DieterW
 2004-04-14 03:03
#32017 #32017
User since
2004-04-14
5 Artikel
BenutzerIn
[default_avatar]
---------------------------------
OK,

ThanX
-Dieter
esskar
 2004-04-14 03:05
#32018 #32018
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
an DieterW: ES IST NICHT MÖGLICH! :)
Wenn das script beendet wird, dann wird auch die datenbankverbindung zu gemacht...
ist doch normal...
nur weil es perl ist, ist es keine wunderwaffe...
oder schafst du es in irgendeiner sprache ein programm zu schreiben, dass einen Socket auf macht und dieser Socket aufbelibt, auch wenn du das programm beendest? Nein!
Also, ignorier mich nicht! *gg*
Ne, spaß bei Seite.
Du musst wohl oder übel auf sessions umsteigen...
ist aber kein problem...
DieterW
 2004-04-17 16:00
#32019 #32019
User since
2004-04-14
5 Artikel
BenutzerIn
[default_avatar]
[quote=esskar,14.04.2004, 01:05]an DieterW: ES IST NICHT MÖGLICH! :)
Wenn das script beendet wird, dann wird auch die datenbankverbindung zu gemacht...
ist doch normal...
nur weil es perl ist, ist es keine wunderwaffe...
oder schafst du es in irgendeiner sprache ein programm zu schreiben, dass einen Socket auf macht und dieser Socket aufbelibt, auch wenn du das programm beendest? Nein!
Also, ignorier mich nicht! *gg*
Ne, spaß bei Seite.
Du musst wohl oder übel auf sessions umsteigen...
ist aber kein problem...[/quote]
Die Antwort mit dem solo "OK" ;) war für dich
gedacht - habe wohl auf den falschen Antwort-Button
gekickt.

Gruß
-DieterW
Gast Gast
 2004-04-17 16:27
#32020 #32020
Hallo DieterW,

db-connect mach ich immer so:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sub mysql_connect {
   my $dbh = DBI->connect(
"dbi:mysql:database=$config{'db_name'}:host=localhost",
   $config{'dbuser'},
   $config{'dbpwd'},
{
   PrintError => 0,
   RaiseError => 1,
   LongReadLen => $config{'LongReadLen'},
   LongTruncOk => 0
}
   ) or oops($DBI::errstr);
   
   return $dbh;
}


dann hat sich das Doppel-Quoting auch erledigt.

Gruß
Dieter
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2004-04-12 04:26.