Aqua: MySQL: $sth->finish; dazwischen rein? // doppelt $sth u. $dbh ??

Hallo!

Mein momentantes Script sieht so aus:

================================================================

#!/usr/bin/perl

use DBI;
use strict;
use CGI;

my $cgi = CGI->new();

print "Content-type: text/plain\n\n";

my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;
my $sth = $dbh->prepare("INSERT INTO customers VALUES (?, ?)")  || die $dbh->errstr;
$sth->execute('', 'User') || die $sth->errstr;

$sth->finish;

$dbh->disconnect;

================================================================

DBI.pm  sagt zu  $sth->finish;

Indicate that no more data will be fetched from this statement handle
before it is either executed again or destroyed. The finish method
is rarely needed, and frequently overused, but can sometimes be
helpful in a few very specific situations to allow the server to free
up resources (such as sort buffers).

================================================================

Meine Frage:

Wenn ich nicht nur einmal was einfügen will,
sondern im selben script noch was SELECT'ieren will,
muss ich dann das $sth->finish dann trotzdem an dieser
Stelle schreiben wo es jetzt ist und danach nochmals
$sth->prepare(...)  machen,
oder darf ich das $sth->finish;  erst vor dem disconnect
schreiben?

Nehmen wir der einfachheit noch ein INSERT an auch wenn
das beispiel blöd ist und mit $dbh->do gehen würde,
es geht nur ums testen:

============================================================

#!/usr/bin/perl

use DBI;
use strict;
use CGI;

my $cgi = CGI->new();

print "Content-type: text/plain\n\n";

my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;
my $sth = $dbh->prepare("INSERT INTO customers VALUES (?, ?)")  || die $dbh->errstr;
$sth->execute('', 'User') || die $sth->errstr;

############################################

$sth->finish;  ###  HIER LASSEN ODER WEG ???

#############################################

$sth = $dbh->prepare("INSERT INTO foobar VALUES (?, ?, ?, ?)")  || die $dbh->errstr;
$sth->execute('', 'a', 'b', 'c') || die $sth->errstr;

$sth->finish;
$dbh->disconnect;

============================================================

2 Fragen dazu:

  1. Gehört das $sth->finish;  da dazwischen rein oder nicht?
  2. da sind zwei mal $sth = $dbh->prepare()  drinnen
       und  auch doppelt das $sth->execute.

Sollte ich beim 2. mal andere namen verwenden wie
$sth_2   und $dbh_2   damit das keine Probleme macht
weil da oben schonmal $dbh und $sth verwendet wurde??

(Bezieht sich aufs 2. Statement  UNTER $sth->finish;)

Vielen lieben Dank
Aqua

  1. hi ...

    So in der Art laufen meine Gedanken gerade ...

    Script No. 1

    #!/usr/bin/perl

    use DBI;
    use strict;
    use CGI;

    my $cgi = CGI->new();

    print "Content-type: text/plain\n\n";

    my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;
    my $sth = $dbh->prepare("INSERT INTO customers VALUES (?, ?)")  || die $dbh->errstr;
    $sth->execute('', 'User') || die $sth->errstr;

    WICHTIGE ZEILE

    $sth->finish;

    HIER VERWENDE ICH $sth UND $dbh NOCHMALS!

    $sth = $dbh->prepare("INSERT INTO foobar VALUES (?, ?, ?, ?)")  || die $dbh->errstr;
    $sth->execute('', 'a', 'b', 'c') || die $sth->errstr;

    $sth->finish;
    $dbh->disconnect;

    =====================================================================================

    Script No. 2

    #!/usr/bin/perl

    use DBI;
    use strict;
    use CGI;

    my $cgi = CGI->new();

    print "Content-type: text/plain\n\n";

    my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;
    my $sth = $dbh->prepare("INSERT INTO customers VALUES (?, ?)")  || die $dbh->errstr;
    $sth->execute('', 'User') || die $sth->errstr;

    ##  ACHTUNG

    HIER IST _KEIN_ $sth->finish MEHR!

    ##  HIER VERWENDE ICH WIEDER DIE SELBEN NAMEN $sth UND $dbh

    $sth = $dbh->prepare("INSERT INTO foobar VALUES (?, ?, ?, ?)")  || die $dbh->errstr;
    $sth->execute('', 'a', 'b', 'c') || die $sth->errstr;

    $sth->finish;
    $dbh->disconnect;

    =====================================================================================

    Script No. 3

    #!/usr/bin/perl

    use DBI;
    use strict;
    use CGI;

    my $cgi = CGI->new();

    print "Content-type: text/plain\n\n";

    my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;
    my $sth = $dbh->prepare("INSERT INTO customers VALUES (?, ?)")  || die $dbh->errstr;
    $sth->execute('', 'User') || die $sth->errstr;

    ACHTUNG:

    HIER IST WIEDER EIN FINISH obwohl danach noch ein $sth kommt!!

    $sth->finish;

    ##  HIER VERWENDE ICH $second_$sth  für $sth damit es zu keinen

    Problemen kommt (hoffe ich)

    $second_sth = $dbh->prepare("INSERT INTO foobar VALUES (?, ?, ?, ?)")  || die $dbh->errstr;
    $second_sth->execute('', 'a', 'b', 'c') || die $sth->errstr;

    $second_sth->finish;
    $dbh->disconnect;

    =====================================================================================

    Script No. 4

    #!/usr/bin/perl

    use DBI;
    use strict;
    use CGI;

    my $cgi = CGI->new();

    print "Content-type: text/plain\n\n";

    my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;
    my $sth = $dbh->prepare("INSERT INTO customers VALUES (?, ?)")  || die $dbh->errstr;
    $sth->execute('', 'User') || die $sth->errstr;

    ##  ACHTUNG HIER IST KEIN FINISH !

    ##  Hier ist wieder $second_sth  und so...

    $second_sth = $dbh->prepare("INSERT INTO foobar VALUES (?, ?, ?, ?)")  || die $dbh->errstr;
    $second_sth->execute('', 'a', 'b', 'c') || die $sth->errstr;

    $second_sth->finish;
    $dbh->disconnect;

    =====================================================================================

    ANMERKUNG

    Mir ist unklar wie das gehen soll.
    Das sind _TEST-Scripte_ !

    Also normalerweise würde ich wegen 2 INSERT's sowas
    nicht machen aber das icst nur zum lernen!

    Danke,
    Aqua

  2. Hallo,

    my $dbh = DBI->connect('DBI:mysql:database=foobar;host=localhost', '', '') || die $dbh->errstr;

    $dbh->errstr ist im Fehlerfalle nicht auswertbar, da $dbh undefined ist. Verwende hier $DBI::errstr.

    1. Gehört das $sth->finish;  da dazwischen rein oder nicht?

    Intern gibt afaik finish() nur offene Datenbank-Cursor frei, die bei Abfragen (SELECT) erzeugt werden. Einige DBD-Module geben eine Warnung aus, wenn solche Cursor nicht geschlossen werden bevor ein disconnect() erfolgt.

    finish() ist in Deinem Falle alos imho Fleißarbeit.

    Sollte ich beim 2. mal andere namen verwenden wie
    $sth_2   und $dbh_2   damit das keine Probleme macht
    weil da oben schonmal $dbh und $sth verwendet wurde??

    Einen zweiten Datenbank-Handle zu öffnen ist mehr als überflüssig. Das bindet nur unnötige Ressourcen. Wenn DU eventuell mal auf eine ander Datenbank wechselst (z.B. Oracle) könnte das erhebliche Performanceeinbußen verursachen, da Oracle einen ziemlich aufwendigen Connect besitzt.

    Zwei Statement-Handle können aber durchaus Sinn ergeben. Allein schon wegen der Übersicht und leichteren Lesbarkeit des Codes greife ich nur dann auf das neutrale $sth zurück, wenn der damit verbundene COde nicht so komplex ist, als dass der ganze Zusammenhang auf einem Blick ersichtlich ist.
    Variablennamen sind ja u.a. deshalb frei wählbar, um damit auszudrücken, was 'in der Variable drinsteht'. $sth und $sth_2 ist ungefähr genauso aussagekräftig wie $foo und $bar. $sth_insert_customer bzw. $sth_update_foobar wäre imho wesentlich besser lesbar.

    Grüße
      Klaus