Frickelmeister: Kann DB nicht auslesen (PERL)?

Hola,
ich habe jetzt mal grob die mySQL Doku überflogen, damit ich überhaupt mal ein wenig Ahnung davon habe, wie ich überhaupt eine DB anlege. Ich habe mit PHPmyAdmin von meinem Webspace aus 2 Spalten (vorname und nachname) angelegt und mit einem Wert gefüttert. Jetzt wollte ich mit einem Perl Script diese Werte im Browser ausgeben lassen, aber bekomme folgende Meldung?
Can't connect(DBI::mysql::db12640001:xxxx.c.artfiles.de xxxxxxxxx 40148668 HASH(0x80f560c)), no database driver specified and DBI_DSN env var not set at /home/www/doc/xxxx/xxxxxxxx/datenbanktest.cgi line 12
Was soll das sein?
Hier mal das Script:

#!/usr/bin/perl -w

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

my $database = 'xxxxxx';
my $dbserver = 'xxxxxc.artfiles.de';
my $user = 'xxxxxx';
my $pass = 'xxxxxx';

my $dbh = DBI->connect("DBI::mysql::$database:$dbserver", $user, $pass, { RaiseError => 1, AutoCommit => 0 }) or die "Cant connect : $!\n";
my $sth = $dbh->prepare("SELECT * FROM haupttabelle") or die "Cant prepare : $!\n";
$sth->execute or die "cant execute : $!\n";

print "Content-type:text/html\n\n";
while (my @row = $sth->fetchrow_array)   {
print "@row\n";
}

$dbh = DBI->disconnect;
Wozu dient überhaupt dieses execute?
Hier http://search.cpan.org/dist/DBI/DBI.pm#Outline_Usage findet man nur folgende Zeilen:

$sth = $dbh->prepare("SELECT foo, bar FROM table WHERE baz=?");

$sth->execute( $baz );

while ( @row = $sth->fetchrow_array ) {
    print "@row\n";
  }
Worauf bezieht sich $baz ?
Ich bin genauso schlau wie vorher.
Ich hoffe jemand kann mir diese Noob Fragen beantworten, danke.

Frickelmeister.

  1. Hi,

    es gibt bei der DBI - Geschichte ein paar Namenskonventionen:

    #!/usr/bin/perl
    use DBI;

    Erzeugen des DB Handlers fuer eine ODBC Datenquelle (MS Access)

    my $dbh = DBI->connect('dbi:ODBC:netlab');

    Oder ein Handler fuer mySQL

    my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
    my $dbh = DBI->connect($dsn, $user, $password);

    Erzeugen des DB Handlers:

    my $dbh = DBI->connect('dbi:ODBC:netlab');

    also: dbh DataBaseHandler

    Erzeugen eines Handlers fuer das SQL Statement

    my $sth = $dbh->prepare("CREATE TABLE names (id INTEGER, name VARCHAR(20), vname VARCHAR(20))");

    also sth: Statement Handler

    Statement ausfuehren

    $sth->execute();

    Beenden und Disconnect

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

    Aus meiner Doku http://i-netlab.de/cgi-bin/index.cgi?vi=DBI_PERL

    Gruss, Erwin

    --
    SELFforum - Das Tor zur Welt!
    Theoretiker: Wie kommt das Kupfer in die Leitung?
    Praktiker: Wie kommt der Strom in die Leitung?
    1. Hola,
      hab jetzt ein paar kleine Änderungen durchgeführt und es klappt.

      Frickelmeister.

      1. Hola Frickelmeister,

        hab jetzt ein paar kleine Änderungen durchgeführt und es klappt.

        Coole Mucke - freut mir wenns geht!!!

        Viele Grüße, schöne Sonntag mosche, Erwin

        --
        Lieber ein Bier nach dem Schnaps als einen Kreislauf-Kollaps!
        1. Was genau macht eigentlich dieses while (my @rows = $auslesen->fetchrow_array)    { ?
          Ich kann nichts anderes machen, als die Daten in einer Wurscht von links nach rechts auszugeben? Ich will mit diesen ausgelesenen Daten auch etwas machen, und nicht nur dumm ausgeben, aber wie kann ich darauf zugreifen? Ich weiß nicht, wie Perl dieses (my @rows = $auslesen->fetchrow_array) behandelt. Liest es die ganze DB da ein? Anscheinend nicht, weil ich mit einer foreach Schleife @rows nicht ausgeben lassen kann, wenn ich es nicht mit while mache, so wie hier. Es würde nämlich dann nur die erste Zeile der Db ausgegeben werden, aber wieso?
          Hier der Code:

          .
          .
          .
          my $dbh = DBI->connect("DBI:mysql:$database:$dbserver", $user, $pass, {AutoCommit => 0}) or die "Cant connect : $!\n";
          my $auslesen = $dbh->prepare("SELECT * FROM haupttabelle") or die "Cant auslesen : $!\n";

          $auslesen->execute;

          print "Content-type:text/html\n\n";
          while (my @rows = $auslesen->fetchrow_array)    {
          print "@rows\n";
          }

          $auslesen->finish;
          $dbh->disconnect;

          Frickelmeister.

          1. use Mosche;

            Bevor ich anfange: ein Tupel ist eine Zeile deines Ergebnissatzes

            Was genau macht eigentlich dieses while (my @rows = $auslesen->fetchrow_array)    { ?
            Ich kann nichts anderes machen, als die Daten in einer Wurscht von links nach rechts auszugeben? Ich will mit diesen ausgelesenen Daten auch etwas machen, und nicht nur dumm ausgeben, aber wie kann ich darauf zugreifen? Ich weiß nicht, wie Perl dieses (my @rows = $auslesen->fetchrow_array) behandelt. Liest es die ganze DB da ein? Anscheinend nicht, weil ich mit einer foreach Schleife @rows nicht ausgeben lassen kann, wenn ich es nicht mit while mache, so wie hier. Es würde nämlich dann nur die erste Zeile der Db ausgegeben werden, aber wieso?

            In @rows steht jetzt ein Tupel.
            Du hast mehrere Möglichkeiten, deine Ergebnisse aus der Datenbank zurückzubekommen.
            Dazu sind alle fetch* Methoden das Statement-Handles gemacht (auch ich empfehle dir, das Ding $sth zu nennen. Grund: alle nennen es so, das macht deinen Code lesbarer für alle). Welche es alle gibt, kannst du in der DBI-Dokumentation (perldoc DBI, auch unter http://www.perldoc.com/) herausfinden.

            Mit einem fetchrow_array bekommst du ein Tupel (fetch_row_) des Ergebnisses zurück, und zwar als Array. Dann gibt es das ganze noch als fetchrow_hashref, dass ist der Rückgabewert eine Referenz auf einen Hash, in denen die keys die Namen der Spalten sind, die Werte sind die Inhalte deines Tupels.

            Du kannst auch fetchall_*-Methoden verwenden, die liefern dann Referenzen auf auf den gesamten Ergebnissatz zurück (fetchall_arrayref, fetchall_hashref).

            Zu deiner Frage mit dem execute - durch die DBI-Spezifikation ist es den einzelnen Datenbanktreibern (DBD::mysql zB) möglich, das interpretieren deines SQL-Kommandos in zwei  Schritten zu erledigen: zuerst wird das Kommando "geprüft" und es findet eine erste "Übersetzung" statt, allerdings kann es noch Platzhalter geben. Erst mit dem execute werden etwaige Platzhalter überschrieben und das Kommando wird ausgeführt. Bei gewissen Programen kann das dein Programm erheblich beschleunigen.

            use Tschoe qw(Matti);

            --
              Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
            1. Hola,

              danke für deine Hilfe, aber ich bin leider noch immer so schlau wie vorher.

              In @rows steht jetzt ein Tupel.

              Was ist ein Tupel?

              Kannst du mir vielleicht ein Beispiel geben, wie ich die Werte aus der Spalte "vorname" und "nachname" nacheinander zB als Vorname = $vorname, Nachname = $nachname ausgeben kann. Ich blicke da wirklich nicht durch.
              Warum ich außerdem $ausgeben nicht als $sth geschrieben habe, liegt daran, dass ich mehrere Sachen zugleich gemacht habe, also schreiben und ausgeben.

              my $auslesen = $dbh->prepare("SELECT * FROM haupttabelle") or die "Cant auslesen : $!\n";
              my $einfuegen = $dbh->prepare("INSERT INTO haupttabelle (vorname,nachname) VALUES ('Markus','Frickelmeister')") or die $dbh->errstr;

              Wie hätte ich es machen sollen, dass ich beides als $sth bezeichne? So hätte ich ständig $sth mit dem neuen "prepare" zuweisen müssen, aber so habe ich mehrere "prepares" beisammen, und kann immer wieder $auslesen, oder $einfuegen aufrufen. Ich dachte man macht es so, oder wie gehen andere hierbei vor? Ich wüsste keine andere Möglichkeit?

              Frickelmeister.

              1. use Mosche;

                In @rows steht jetzt ein Tupel.
                Was ist ein Tupel?

                Schau mal an den Anfang meines ersten Postings:
                Ein Tupel ist eine Zeile des Ergebnissatzes.

                Du bekommst als Ergebnis deiner Abfrage eine Tabelle zurückgeliefert - diese hat Spalten, wbei in jeder Spalte ein sog. Attribut (bei dir: Vorname/Nachname) steht. Eine Zeile, die zusammengehörende Attribute enthält (Vorname = "Matti" gehört zu Nachname = "Mäkitalo") heißt Tupel.

                Ein Tupel wäre hier also ("Matti", "Mäkitalo")

                Kannst du mir vielleicht ein Beispiel geben, wie ich die Werte aus der Spalte "vorname" und "nachname" nacheinander zB als Vorname = $vorname, Nachname = $nachname ausgeben kann. Ich blicke da wirklich nicht durch.

                my $sth = $dbh->prepare("SELECT vorname, nachname FROM haupttabelle;");
                $sth->execute;

                while(my @row = $sth->fetchrow_array) {

                oder anders:

                while (my ($vorname, $nachname) = $sth->fetchrow_array) {

                print "Vorname = '$row[0]', Nachname = '$row[1]'\n";

                bzw:

                #   print "Vorname = '$vorname', Nachname = '$nachname'\n";
                }

                Eigentlich ganz einfach, oder?

                use Tschoe qw(Matti);

                --
                  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
                1. Hola,
                  da hab ich wohl den Wald vor lauter Bäumen nicht mehr gsehen. Jetzt kann ich mir das vorstellen und es funktioniert, danke.;)

                  Frickelmeister.