ceejay: MySQL, PERL und PHP

erstmal vorneweg nehmen möchte ich, das ich ab ca. 15. 08. 2000
auf meiner eigenen Maschine hosten werde, was auch anderen zugute kommen soll, in dem Ihr die Möglichkeit habt, dort MySQL, PERL und PHP in einer Linux mit Apache - Umgebung nutzen könnt(et).

Wer Interesse hat, möchte sich melden - aber dran denken, das essen wird langsam warm - zu schnell kochen verdirbt den Geschmack,
ergo Eile mit Weile ;)=

--- snip
Nun zu meinem kleinen Problem:
unter PHP gibts die Möglichkeit/Funktion:

$anzahl = mysql_num_fields{'datenbank');

um die Anzahl, und mit

for( $i=0; $i < $anzahl; $++ ) {
echo mysql_num_fields{'datenbank',$i);
}

kann ich die entsprechenden Feldnamen ausgeben...

Frage: Wie komme ich in PERL gescheit an diese Feldnamen ran ?

---
Nach entsprechendem Connect, Prepare und Execute, kann ich in PERL
die Daten in einem HASH zurückkriegen.

While( $record_hash = $sth->fetchrow_hashref() ) {
my $ausgabe;
$ausgabe.= "\tID: ".$record_hash->{ID};
$ausgabe.= "\tName: ".$record_hash->{Name};
$ausgabe.= "\tKontinent: ".$record_hash->{Kontinent};
$ausgabe.= "\tLand: ".$record_hash->{Land};
$ausgabe.= "\tStadt: ".$record_hash->{Stadt};
}
das funktioniert auf diese Weise auch ganz gut, aber kann mir bitte jemand sagen wieso ich mit:

foreach $Feld (keys %record_hash) {
$ausgabe .= "Feldname: ".$Feld."\tInhalt: ".$record_hash{$Feld}."\n";
}
print $ausgabe;
}

innerhalb der while schleife keine Daten erhalte ?
auch mit print $record_hash{'Name'} kriege ich keinen Output ('Name' ist auch einer der Feldnamen) ?

Ich fänds nicht schlecht, mit der Routine nicht nur die Daten aus der Datenzeile zu erhalten, sondern auch "per keys %hash" zugriff auf den Feldnamen zu kriegen.

In diesem Zusammenhang liesse sich eine "generierende" Seite erzeugen, in der man eben nur die Feldnamen "tagged" (z.B. <!Name!> <!Nachname!> ) und mit s/<!$suchtag!>/$record_hash{$suchtag}/g; die entsprechenden Werte "sucht und ersetzt" ....

  1. hallo ceejay,

    While( $record_hash = $sth->fetchrow_hashref() ) {
    my $ausgabe;

    ...

    foreach $Feld (keys %record_hash) {

    »»  $ausgabe .= "Feldname: ".$Feld."\tInhalt: ".$record_hash{$Feld}."\n";
    »»  }

    '$record_hash' ist _kein_ Hash. Es ist eine Referenz auf ein Hash.
    '$record_hash'  und '%record_hash'  sind zwei verschiedene Dinge.Das ist Dein Problem.
    es sollte vielmehr lauten:

    foreach $Feld (keys %$record_hash)
       {
       $ausgabe .= "Feldname: ".$Feld."\tInhalt: ".$record_hash->{$Feld}."\n";
       }

    Da sind zwar _nur_ drei Zeichen mehr, aber das machts voll aus.

    Andererseits:

    mit '$sth->{NAME}' bekommst Du eine Array-Referenz auf die im SQL-Statement verwendeten Felder zurück.
    Dadurch könnte es so aussehen (jetz mal ohne Fehlerbehandlung):

    $sth = $dbh->prepare($sql_statement);
    $sth->execute();

    while ($werte = $sth->fetch_arrayref)
      {
      my($ausgabe);
      for my $idx (0 .. $#{$sth-{NAME} )
         {
         $ausgabe .= 'Feldname: ' . $sth-{NAME}->[$idx] . "\tInhalt: " . $werte->[$idx] . "\n";
         }
       }

    Der Vorteil einer Methode wie dieser ist der, daß die Felder in der richtigen. entsprechend dem Statement angeordneten, Reihenfolge ausgelesen werden, und nicht, wie bei einem Hash, in einer 'zufälligen'.
    Außerdem, so hab ich mir sagen lassen, ist's auch schneller, weil das DD-Modul nicht noch extra ein Hash erzeugen muß.

    (Ich hoffe, ich hab' jetzt nirgendwo einen Tippfehler drin, oder sonst einen Wurm. Hab's wieder mal nicht getestet :-( )

    Grüße
      Klaus

    1. hallo ceejay,

      While( $record_hash = $sth->fetchrow_hashref() ) {
      my $ausgabe;
      ...
      foreach $Feld (keys %record_hash) {
      »»  $ausgabe .= "Feldname: ".$Feld."\tInhalt: ".$record_hash{$Feld}."\n";
      »»  }

      '$record_hash' ist _kein_ Hash. Es ist eine Referenz auf ein Hash.
      '$record_hash'  und '%record_hash'  sind zwei verschiedene Dinge.Das ist Dein Problem.
      es sollte vielmehr lauten:

      foreach $Feld (keys %$record_hash)
         {
         $ausgabe .= "Feldname: ".$Feld."\tInhalt: ".$record_hash->{$Feld}."\n";
         }

      Da sind zwar _nur_ drei Zeichen mehr, aber das machts voll aus.

      Andererseits:

      mit '$sth->{NAME}' bekommst Du eine Array-Referenz auf die im SQL-Statement verwendeten Felder zurück.
      Dadurch könnte es so aussehen (jetz mal ohne Fehlerbehandlung):

      $sth = $dbh->prepare($sql_statement);
      $sth->execute();

      while ($werte = $sth->fetch_arrayref)
        {
        my($ausgabe);
        for my $idx (0 .. $#{$sth-{NAME} )
           {
           $ausgabe .= 'Feldname: ' . $sth-{NAME}->[$idx] . "\tInhalt: " . $werte->[$idx] . "\n";
           }
         }

      Der Vorteil einer Methode wie dieser ist der, daß die Felder in der richtigen. entsprechend dem Statement angeordneten, Reihenfolge ausgelesen werden, und nicht, wie bei einem Hash, in einer 'zufälligen'.
      Außerdem, so hab ich mir sagen lassen, ist's auch schneller, weil das DD-Modul nicht noch extra ein Hash erzeugen muß.

      (Ich hoffe, ich hab' jetzt nirgendwo einen Tippfehler drin, oder sonst einen Wurm. Hab's wieder mal nicht getestet :-( )

      Grüße
        Klaus

      ahja, eine refrenz - hab ich doch irgendwo schonmal vernommen ... ;)=
      jo, sieht gut aus, denke das dürfte das problem lösen - auch wenn och wahrscheinlich eine weile brauchen werde, um dein source zu kapieren *kicher* - übrigens in der DBI MYSQL FAQ auf http://dbimysql.photoflux.com/ gibts zu diesem Zusammenhang gute Ergänzungen - die weitere Fragen aufwerfen *ggG*

      da ist zum beispiel ein artikel, in dem "fetchrow_array" gegen "fetchrow_hashref" gesetzt wird, und die zeiten die dabei gemessen wurden sind echt krass ... naja schau selbst:

      Output: Benchmark: timing 1000 iterations of array, hashref...
        array:  9 wallclock secs ( 3.25 usr + 0.40 sys = 3.65 CPU)
      hashref: 20 wallclock secs ( 7.85 usr + 0.49 sys = 8.34 CPU)
      Small query, small record set, but well over twice the penalties for hashrefs.

      daher die Frage (Wo ist mein MySQL/Perl-Buch ? ;)= ) wie kriege ich die Feldnamen am günstigsten, gibts nicht eine Funktion wie:
      while( $Field = fetchrow_fieldid() ) {} ????

      es grüßt
      c.J.

      1. hallo ceejay,

        da ist zum beispiel ein artikel, in dem "fetchrow_array" gegen "fetchrow_hashref" gesetzt wird, und die zeiten die dabei gemessen wurden sind echt krass ... naja schau selbst:

        Output: Benchmark: timing 1000 iterations of array, hashref...
          array:  9 wallclock secs ( 3.25 usr + 0.40 sys = 3.65 CPU)
        hashref: 20 wallclock secs ( 7.85 usr + 0.49 sys = 8.34 CPU)
        Small query, small record set, but well over twice the penalties for hashrefs.

        Sag ich doch mit fetchrow_array gehts schneller, weil kein Hash gebildet werden muß.

        daher die Frage (Wo ist mein MySQL/Perl-Buch ? ;)= )

        'mSQL & MySQL' von O'Reilly. Da wird nicht nur die Datenbank, sond auch deren umgang mit C,Perl und PHP besprochen. echt gut
        'Programming the Perl DBI' von O'Reilly. auch gut.

        wie kriege ich die Feldnamen am günstigsten, gibts nicht eine Funktion wie:

        $sth->{NAME} liefert eine Referenz auf ein Array mit den Namen retour
        SIehe meine erste Nachricht ab 'Andererseits:'.
        Grüße
           Klaus