mehr als 407 Zeichen mit "$x->func('dbms_output_get');" lesen
Ronny Riedel
- perl
0 Ronny Riedel0 Ronny Riedel0 hotti0 Alexander (HH)0 hotti
Hallo zusammen,
gegeben sei folgendes PERL-Skript:
#!/usr/bin/perl
use strict;
use DBI;
# die Umgebungsvariable "ORACLE\_HOME" muss gesetzt werden
$ENV{ORACLE\_HOME} = '/path/to/oracle/10.2.0';
# DB-Verbindung oeffnen und initialisieren
my $dbh = DBI->connect("dbi:Oracle:[db]", '[user]', '[pw]');
$dbh->{RaiseError} = 1;
$dbh->func(1000000, 'dbms\_output\_enable');
# PL/SQL-Prozedur der DB aufrufen
my $csr = $dbh->prepare(q{
BEGIN
FOR i IN 1 .. 407 LOOP
dbms\_output.put('a');
END LOOP;
--
dbms\_output.new\_line;
END;
});
$csr->execute;
# alle Daten aus dem Puffer von "dbms\_output" holen
my @ausgaben = $dbh->func( 'dbms\_output\_get' );
# diese Daten in eine Datei schreiben
foreach my $ausgabe (@ausgaben) {
print $ausgabe;
print "\n";
}
# DB-Verbindung schliessen
$dbh->disconnect;
~~~~~~~~~~~~~~~~~~~~~~~~~~~ snap ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wenn ich das Skript aufrufe, dann erhalte ich 407 mal "a" als ein langer String. Wenn ich jetzt allerdings aus der 407 eine 408 mache, dann erhalte ich gar nichts.
Kann mir bitte jemand erklären, warum das so ist?
Danke & Gruß
Ronny R.
Anmerkung:
my $csr = $dbh->prepare(q{
BEGIN
FOR i IN 1 .. 407 LOOP
dbms_output.put('a');
END LOOP;
--
dbms_output.new_line;
dbms_output.put_line('Hello World');
END;
});
aaaaa[...]aaaa
Hello World
Jedoch
my $csr = $dbh->prepare(q{
BEGIN
FOR i IN 1 .. 408 LOOP
dbms_output.put('a');
END LOOP;
--
dbms_output.new_line;
dbms_output.put_line('Hello World');
END;
});
produziert gar keinen Output
getestet unter:
user@host1> perl -v
This is perl, v5.10.0 built for x86_64-linux-thread-multi
Copyright 1987-2007, Larry Wall
und unter:
user@host2{~} perl -v
This is perl, v5.8.8 built for x86_64-linux-thread-multi
Copyright 1987-2006, Larry Wall
hi,
Du hast $dbh->{RaiseError} = 1; gesetzt. Nutze es auch, prüfe ob eine Exception auftritt und teste die Prozedur auch mal unabhängig von Perl.
use English; # now, $@ means $EVAL_ERROR
Hotti
Moin Moin!
hi,
Du hast $dbh->{RaiseError} = 1; gesetzt. Nutze es auch, prüfe ob eine Exception auftritt
Mumpitz! Da ist kein eval weit und breit, Exceptions hätten das Script sofort beendet.
und teste die Prozedur auch mal unabhängig von Perl.
use English; # now, $@ means $EVAL_ERROR
Was kaum jemandem nützt und in dieser Form jeglichen Code, der RegExps benutzt, massiv ausbremst.
"Wenn man keine Ahnung hat: Einfach mal Fresse halten." -- Dieter Nuhr
Alexander
Moin Moin!
Du hast $dbh->{RaiseError} = 1; gesetzt. Nutze es auch, prüfe ob eine Exception auftritt
Mumpitz! Da ist kein eval weit und breit,
Stimmt, ich habe es bereits beim ->connect vermisst;
Exceptions hätten das Script sofort beendet.
Korrekt.
use English; # now, $@ means $EVAL_ERROR
Was kaum jemandem nützt
Das erkläre besser demjenigen, der {RaiseError} = 1; setzt und nicht einmal merkt, dass es
RaiseError => 1
Heißen muss. Ich habs auch nicht gleich gesehen ;)
"Wenn man keine Ahnung hat: Einfach mal Fresse halten." -- Dieter Nuhr
Woher kommt eigentlich der Ausdruck 'Fresse'? Ich dächte aus dem Thüringischen, also irgendwie aus dem nördlichen Sprachraum. Da jedoch wohnen Fischköppe und die haben ein 'Maul'.
Hotti
Hallo nochmal,
zu
Das erkläre besser demjenigen, der {RaiseError} = 1; setzt und nicht einmal merkt, dass es
RaiseError => 1
>
> Heißen muss. Ich habs auch nicht gleich gesehen ;)
Ich hab das von hier: "http://search.cpan.org/~pythian/DBD-Oracle-1.23/Oracle.pm#plsql\_errstr". Im "Example" steht eben
~~~perl
$dbh->{RaiseError} = 1;
Wenn die das schon nicht richtig machen, wer dann?
Grüße
Ronny R.
Moin Moin!
Hotti hat keinen Plan. Er frickelt auf Anfängerniveau mit Perl herum und hält sich für den Oberexperten.
Ich hab das von hier: "http://search.cpan.org/~pythian/DBD-Oracle-1.23/Oracle.pm#plsql_errstr". Im "Example" steht eben
$dbh->{RaiseError} = 1;
>
> Wenn die das schon nicht richtig machen, wer dann?
<erbsenzähler>Die [DBI](http://search.cpan.org/perldoc?DBI)-Autoren.</erbsenzähler>
Es ist richtig.
Es gibt im Grunde zwei unterschiedliche Varianten, das [RaiseError](http://search.cpan.org/~timb/DBI-1.616/DBI.pm#RaiseError)-Attribut zu setzen.
Entweder als Attribut-Hash-Argument für die [connect](http://search.cpan.org/~timb/DBI-1.616/DBI.pm#connect)-Methode bzw. die [connect_cached](http://search.cpan.org/~timb/DBI-1.616/DBI.pm#connect_cached)-Methode:
`my $dbh=DBI->connect(...,...,...,{ RaiseError => 1, ... });`{:.language-perl}
Oder indem Du das Attribut direkt setzt:
`$dbh->{'RaiseError'}=1;`{:.language-perl}
Der feine Unterschied ist, dass die erste Variante schon während des connect() wirkt, d.h. ein fehlgeschlagenes connect() löst eine Exception aus. Die zweite Variante wirkt natürlich erst ab der Zuweisung, sollte connect() fehlschlagen, ist $dbh einfach nicht definiert (undef). Das führt dazu, dass Code à la `$dbh->{'SomeAttribute'}=SomeValue`{:.language-perl} bzw. `$dbh->someMethod(...)`{:.language-perl} "viel" später auf die Nase fällt ("Can't call method "someMethod" on an undefined value" bzw. "Can't use an undefined value as a HASH reference"). Daher ist die erste Variante zu bevorzugen.
Übrigens ist RaiseError eines der Attribute, die man für alle DBI-Handle-Typen setzen kann. Typischerweise setzt man es für den Datenbank-Handle und DBI vererbt das Attribut an die Statement-Handles, aber man kann das Attribut auch manuell für ein Statement-Handle setzen. (Mir fällt nur gerade nicht ein, warum man das machen wollen würde.)
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
Moin Moin!
Das erkläre besser demjenigen, der {RaiseError} = 1; setzt und nicht einmal merkt, dass es
RaiseError => 1
>
> Heißen muss. Ich habs auch nicht gleich gesehen ;)
UNSINN!
Halt einfach die Klappe, lies die DBI-Doku, und poste erst NACH dem Denken.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
Moin Moin!
Wenn ich das Skript aufrufe, dann erhalte ich 407 mal "a" als ein langer String. Wenn ich jetzt allerdings aus der 407 eine 408 mache, dann erhalte ich gar nichts.
Ich sehe keinen offensichtlichen Fehler, und 407 / 408 (plus ggf. 2 Bytes für CR/LF) ist für meinen Geschmack weit unter einer kritischen Größe für irgendwelche Puffer.
Frag mal bei dbi-users nach.
Oh, und es gibt kein PERL. Perl mit großem P ist die Sprache, perl mit kleinem p ist das Executable, das Perl-Code verdaut.
Alexander
hi,
$dbh->{RaiseError} = 1;
Argh. Damit ist dein Script schon tot bevor es lebendig wird. Deine Fehlerbehandlung ist sehr verbesserungsbedürftig, überarbeite das und dann findest Du auch den Fehler.
Hotti
Moin Moin!
hi,
$dbh->{RaiseError} = 1;
Argh. Damit ist dein Script schon tot bevor es lebendig wird.
UNSINN!
Der Code ist so ok, außer dass er connect()-Fehler nicht abfängt.
Macht aber nichts, weil $dbh bei einem fehlgeschlagenen connect() undefiniert ist und die nächste Zeile das Script mit "Can't use an undefined value as a HASH reference" killt.
Deine Fehlerbehandlung ist sehr verbesserungsbedürftig, überarbeite das und dann findest Du auch den Fehler.
Bullshit.
Verkneif Dir bitte solche Schlaumeier-Antworten, wenn Du vom Thema keine Ahnung hast. Das ist nicht hilfreich für den Fragesteller!
Alexander