Syntaxproblem bei Pfeilfunktion
HP-User
- perl
Abend Forum:
Hier muss irgend etwas falsch sein:
while (my $row = $sth->fetchrow_hashref){
print("name = $row->{Name} 'contact = $row->{Contact}"."\n";
}
Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?
Gruss HP-User
Tach!
while (my $row = $sth->fetchrow_hashref){
print("name = $row->{Name} 'contact = $row->{Contact}"."\n";
}
> Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?
Das kann nur in Abhängigkeit vom Ausgabekontext beantwortet werden. Und den hast du nicht genannt.
dedlfix.
Abend dedlfix
Perlcode:
#!/usr/bin/perl
# sollte in keinem Script fehlen
use strict;
use warnings;
# DBI Modul Laden
use DBI;
# Verzeichnis mit dem Script finden.
# "." muss nicht immer das Verzeichnis mit dem Script sein
use FindBin '$Bin';
# Sollte man machen.
# es hilft die Dateinamen
# von den Tabellennamen zu trennen.
my %zuordnung=(
prospects => {
file => 'prospects.csv',
col_names => ['Name', 'Address', 'Floors', 'Donated last year', 'Contact'],
},
);
# Verbindung aufbauen
my $dbh = DBI->connect("DBI:CSV:", undef, undef, {
# Zeilenseparator
csv_eol => "\x0A",
# Spaltenseparator:
csv_sep_char => ",",
# Verzeichnis mit den Dateien
f_dir => $Bin,
# Zuordnung Dateiname -> Tabelle
csv_tables => \%zuordnung,
# bei Fehlern immer sterben:
RaiseError => 1,
}
) or die($DBI::errstr);
# Testausgabe
my $sth=$dbh->prepare('SELECT * FROM prospects');
$sth->execute();
while(my @row = $sth->fetchrow_array){
print join('; ',@row)."\n";
}
$sth->finish;
my $row;
$sth = $dbh->prepare("SELECT * FROM prospects WHERE name LIKE 'G%'");
$sth->execute();
while (my $row = $sth->fetchrow_hashref){
print("name = $row->{Name} contact = $row->{Contact}"."\n");
}
$sth->finish();
$dbh->disconnect();
CSV-Inhalt (Dateiname: prospects.csv):
-----------------------------------------------------------------------------
"Name","Address","Floors","Donated last year","Contact"
"Charlotte French Cakes","1179 Glenhuntly Rd","1","Y","John"
"Glenhuntly Pharmacy","1181 Glenhuntly Rd","1","Y","Paul"
"Dick Wicks Magnetic Pain Relief","1183-1185 Glenhuntly Rd","1","Y","George"
"Gilmour's Shoes","1187 Glenhuntly Rd","1","Y","Ringo"
-----------------------------------------------------------------------------
Ich versuche mit diesem Übungscode eine DBD::CSV anzusteuern. Das gelingt nur teilweise. Die Ausgabe im Terminal sieht so aus:
-----------------------------------------------------------------------------
Name; Address; Floors; Donated last year; Contact
Charlotte French Cakes; 1179 Glenhuntly Rd; 1; Y; John
Glenhuntly Pharmacy; 1181 Glenhuntly Rd; 1; Y; Paul
Dick Wicks Magnetic Pain Relief; 1183-1185 Glenhuntly Rd; 1; Y; George
Gilmour's Shoes; 1187 Glenhuntly Rd; 1; Y; Ringo
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
name = contact =
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
name = contact =
-----------------------------------------------------------------------------
Irgendwo ist noch ein kleiner Fehler, den ich nicht finden kann.
Gruss HP-User
hi,
Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?
Von außen nach innen und paarweise ;)
print("name = $row->{Name} 'contact = $row->{Contact}' \n";
Tipp: Verwende q() oder qq() für einfach bzw. doppelt quoten, das ist oftmals übersichtlicher.
Hotti
hi,
Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?
Von außen nach innen und paarweise ;)
print("name = $row->{Name} 'contact = $row->{Contact}' \n";
Die Klammern () auch paarweise, da oben fehlt eine ;)
Arrow-Operator:
`print "$row->{Name}\n";`{:.language-perl}
Hier wird dereferenziert, es entsteht ein Scalar, das wird innerhalb der doppelten Anführungszeichen interpoliert. Syntax ok.
Wenn Du eine Methode aufrufst:
`$obj->method();`{:.language-perl}
und das Ergebnis derer gleich ausgeben möchtest, geht das so:
~~~perl
print "@{[$obj->check_email('r.rr@example.com')]}\n";
ohne dass die Rückgabewerte (print erwartet eine Liste) auf einem explizit angegebenen Array aufgefangen werden müssen.
Ein print "@liste";
gibt die Einzelelemente schön sauber durch Leerzeichen getrennt in einer Zeile aus.
Hotti
Hi hotto
Tipp: Verwende q() oder qq() für einfach bzw. doppelt quoten, das ist oftmals übersichtlicher.
Geht auch nicht :-(
Hier das Übungsprogramm. Im ersten Ausgabeteil wird die komplette CSV ausgegeben. Im Zweiten Teil sollte nur Felder mit "G" ausgegebenwerden. Das ganze sollte eine Übung zum ansprechen von CSV-Dateien als DB sein.m Sollte - weil es klappt einfach nicht. Aktueller Perl Code:
#!/usr/bin/perl
# sollte in keinem Script fehlen
use strict;
use warnings;
# DBI Modul Laden
use DBI;
# Verzeichnis mit dem Script finden.
# "." muss nicht immer das Verzeichnis mit dem Script sein
use FindBin '$Bin';
# Sollte man machen.
# es hilft die Dateinamen
# von den Tabellennamen zu trennen.
my %zuordnung=(
prospects => {
file => 'prospects.csv',
col_names => ['Name', 'Address', 'Floors', 'Donated last year', 'Contact'],
},
);
# Verbindung aufbauen
my $dbh = DBI->connect("DBI:CSV:", undef, undef, {
# Zeilenseparator
csv_eol => "\x0A",
# Spaltenseparator:
csv_sep_char => ",",
# Verzeichnis mit den Dateien
f_dir => $Bin,
# Zuordnung Dateiname -> Tabelle
csv_tables => \%zuordnung,
# bei Fehlern immer sterben:
RaiseError => 1,
}
) or die($DBI::errstr);
# Testausgabe Nr.1: ganze CSV
my $sth=$dbh->prepare('SELECT * FROM prospects');
$sth->execute();
while(my @row = $sth->fetchrow_array){
print join('; ',@row)."\n";
}
$sth->finish;
#Textausgabe Nr.2: sortierte CSV
$sth = $dbh->prepare("SELECT * FROM prospects WHERE Name LIKE 'G%'");
$sth->execute();
while (my $row = $sth->fetchrow_hashref){
print qq(name = $row->{Name} contact = $row->{Contact})."\n";
}
$sth->finish();
$dbh->disconnect();
Diese "hash"-Geschichte macht mich echt noch fertig.
Hier die Ausgabe im Terminal inkl. Fehler:
-----------------------------------------------------------------------
Name; Address; Floors; Donated last year; Contact
Charlotte French Cakes; 1179 Glenhuntly Rd; 1; Y; John
Glenhuntly Pharmacy; 1181 Glenhuntly Rd; 1; Y; Paul
Dick Wicks Magnetic Pain Relief; 1183-1185 Glenhuntly Rd; 1; Y; George
Gilmour's Shoes; 1187 Glenhuntly Rd; 1; Y; Ringo
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
name = contact =
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
name = contact =
-----------------------------------------------------------------------
Ziel:
Es soll in der Namespalte alle datensätze angezeigt werden, die ein "G" enthalten oder mit "G" beginnen - so genau hab ich das Beispiel noch nicht verstanden. Aber es sollte doch zumindest ohne Fehlermeldung arbeiten.
Also: Wer einen Anhaltspunkt sieht, was hier falsch läuft, darf es mir gerne mitteilen. Ich bin nach unzähligen Versuchen mit meinem Latein am Ende.
Gruss HP-User
P.S.
(Ich hol mir jetzt erst einmal einen Caffe! Den hab ich mir verdient und der beruhigt die Nerven :-)
Hi lieber Mitstreiter ;)
Tipp: Verwende q() oder qq() für einfach bzw. doppelt quoten, das ist oftmals übersichtlicher.
Geht auch nicht :-(
Abgelehnt! Lerne Quoten ;)
Hier das Übungsprogramm.
Nein, Dein Komplettprogramm werde ich nicht überarbeiten. Du kannst das!
Schrit für Schritt und das Hauruck erst am Schluss ;)
Noch ein paar Grundlagen: Arrays schön und gut, aber Du musst oft nachschauen, auf welchem Index [0], [1] ... welcher Wert zu finden ist. Vorschlag: Arbeite mit einem Hash und nenne die Felder beim Namen.
my @header = qw(Name Vorname Ort PLZ); # Beispiel
my @row_array = ("Rost", "Rolf", "Oppenheim", 55276); # CSV Zeile
my %row_hash = (); # declare
# Hash-Slice
@row_hash{@header} = @row_array; # den Feldern Werte zuweisen
print Dumper \%row_hash;
$VAR1 = {
'PLZ' => 55276,
'Ort' => 'Oppenheim',
'Vorname' => 'Rolf',
'Name' => 'Rost'
};
# Eizelfeld ansprechen
print $row_hash{Name};
# Referenz
my $ref = \%row_hash;
print $ref->{Name};
# bischen quoten
print qq(Name: $ref->{Name})."\n";
# einfacher alles zusammen
print "Name: $ref->{Name\\n";
# quoten und verketten like PHP
$addr = array(
"Name" => "Rost",
);
print("Name: ".$addr['Name']."\n");
Hotti
Hi hotti
Alles klar *g*
Gut, ich habe das ganze Konstrukt entfernt. Alles zurück auf Null!
Ich weiss zwar noch nicht, wie mir dein Array und Hash lergang bei meinem Datenbankprojekt helfen kann, aber Fakt ist, ich habe über diese beiden Dinge wenig Ahnung! Also los...
So sieht übrigens "dein" Lernprog für Perl bis jetzt aus (was auch nicht funktioniert):
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my @header = qw(Name Vorname Ort PLZ); # Beispiel
my @row_array = ("Rost", "Rolf", "Oppenheim", 55276); # CSV Zeile
my %row_hash = (); # declare
# Hash-Slice
@row_hash{@header} = @row_array; # den Feldern Werte zuweisen
print Dumper \%row_hash;
my $VAR1 = {
'PLZ' => 55276,
'Ort' => 'Oppenheim',
'Vorname' => 'Rolf',
'Name' => 'Rost'
};
# Eizelfeld ansprechen
print $row_hash{Name};
# Referenz
my $ref = \%row_hash;
print $ref->{Name};
# bischen quoten
print qq(Name: $ref->{Name})."\n";
# einfacher alles zusammen
print "Name: $ref->{Name}\n";
# quoten und verketten like PHP
my $addr = array("Name" => "Rost",);
print("Name: ".$addr['Name']."\n");
exit();
Bevor wir das auseinanderpflücken, wär es nett, wenn du mir bei der Fehlersuche deines Programms helfen könntest. Ein Paar "my's" hab ich schon hinzugefügt/korrigiert.
Die Fehlermeldung der Terminalausgabe lautet so:
---------------------------------------------------------------------
Global symbol "@addr" requires explicit package name at ./DB-Test.pl line 36.
Execution of ./DB-Test.pl aborted due to compilation errors.
---------------------------------------------------------------------
Der Witz dieser Fehlermeldung: Es gibt gar kein Array "@addr". Manmanman - Computers wat 'n Stress!
Grüsse HP-User
Hi Hotti
Das ursprüngliche Programm funktioniert jetzt. War ein Groß-Kleinschreibeproblem:
print Dumper (my $row = $sth->fetchrow_hashref);
while (my $row = $sth->fetchrow_hashref){
print qq(Name = $row->{name} Contact = $row->{contact})."\n";
}
Also die Klammerwerte {Name} und {Contact} waren klein zu schreiben.
Das interessante daran: Weder im Hauptprogramm zeile 19, noch in der CSV-Datei sind diese Werte kleingeschrieben. Das bedeutet, dass wohn DBI-DBD-CSV die Werte automatisch in kleinen Buchstaben ausliefert?
Na ja, da muss ich noch genauer recherchieren, woher dieser Hash Inhalt herkommt.
Gruss HP
hi,
Also die Klammerwerte {Name} und {Contact} waren klein zu schreiben.
Da gibt es für den connect() ein Attribut DBD::CSV
FetchHashKeyName => "NAME_lc",
Das interessante daran: Weder im Hauptprogramm zeile 19, noch in der CSV-Datei sind diese Werte kleingeschrieben. Das bedeutet, dass wohn DBI-DBD-CSV die Werte automatisch in kleinen Buchstaben ausliefert?
Doku lesen (Mist, macht Arbeit *G*).
(driver flags, wird wohl der Default sein ;)
Na ja, da muss ich noch genauer recherchieren, woher dieser Hash Inhalt herkommt.
Stichwort: col_names
Und auch:
skip_first_row
By default DBD::CSV assumes that column names are stored in the first row of the CSV file ...
Aber schön, dass Du hier mit Perl unterwegs bist!
Hotti