use DBI; @data_sources = DBI->data_sources($driver_name); $dbh = DBI->connect($data_source, $username, $auth); $dbh = DBI->connect($data_source, $username, $auth, \%attr); $rc = $dbh->disconnect; $rv = $dbh->do($statement); $rv = $dbh->do($statement, \%attr); $rv = $dbh->do($statement, \%attr, @bind_values); $sth = $dbh->prepare($statement); $sth = $dbh->prepare($statement, \%attr); $rc = $sth->bind_col($col_num, \$col_variable); $rc = $sth->bind_columns(\%attr, @list_of_refs_to_vars_to_bind); $rv = $sth->bind_param($param_num, $bind_value); $rv = $sth->bind_param($param_num, $bind_value, $bind_type); $rv = $sth->bind_param($param_num, $bind_value, \%attr); $rv = $sth->execute; $rv = $sth->execute(@bind_values); @row_ary = $sth->fetchrow_array; $ary_ref = $sth->fetchrow_arrayref; $hash_ref = $sth->fetchrow_hashref; $rc = $sth->finish; $rv = $sth->rows; $rc = $dbh->commit; $rc = $dbh->rollback; $sql = $dbh->quote($string); $rc = $h->err; $str = $h->errstr; $rv = $h->state;
Da die DBI-Spezifikation momentan einem recht schnellen Wandel unterworfen ist, müssen Sie sicherstellen, daß Sie auch wirklich die neueste Version vorliegen haben.
Der nachfolgende Abschnitt "Letzte Änderungen" faßt alle für den Benutzer sichtbaren Änderungen zusammen. Darüber hinaus finden Sie in der im DBI-Paket enthaltenen Datei Changes detaillierte Informationen zu den Änderungen.
Beachten Sie auch, daß DBI-Änderungen erst mit etwas Verspätung in den Treibern berücksichtigt werden. Neuere DBI-Versionen besitzen viele neue Features, die der von Ihnen benutzte Treiber möglicherweise noch nicht unterstützt. Sprechen Sie mit den Autoren dieser Treiber, wenn Sie diese Features benötigen.
Bitte lesen Sie auch die DBI-FAQ, die als DBI::FAQ-Modul installiert ist, d.h., Sie können perldoc verwenden, um es zu lesen, indem Sie den Befehl perldoc DBI::FAQ ausführen.
execute(@bind_values) in die Dokumentation aufgenommen.
warn(). Der neue DBI->connect-Aufruf setzt nun automatisch PrintError=1, wenn { PrintError => 0 } nicht in den connect-Attributen angegeben wird (siehe connect). Der alte connect mit eigenem Treiberparameter ist veraltet und sollte nicht mehr verwendet werden. $h->debug in $h->trace() umbenannt und ein zusätzliches Argument für eine Trace-Datei hinzugefügt.
Es ist wichtig zu beachten, daß DBI nur eine Schnittstelle darstellt - eine dünne Verbindungsschicht zwischen einer Anwendung und einem oder mehreren Datenbanktreibern (Driver). Die eigentliche Arbeit erledigen die Treiber. Das DBI stellt nur eine Standardschnittstelle und einen (Software-) Rahmen zur Verfügung, innerhalb dessen sich die Treiber bewegen.
An diesem Dokument wird immer noch gearbeitet. Obwohl es unvollständig ist, sollte es hilfreich sein, wenn Sie die Arbeit mit DBI aufnehmen.
|<- DBI-Architektur ->|
.-. .--------------. .-------------.
.----------. | |---| XYZ-Treiber | | XYZ-Engine |
| DBI-API- | |S| '--------------' '-------------'
| Methoden | |A| |w| .--------------. .-------------.
| nutzendes|--|P|--|i|---|Oracle-Treiber|---|Oracle-Engine|
| Perl- | |I| |t| '--------------' '-------------'
| Skript | |c|...
'----------' |h|... Weitere Treiber
| |...
'-'
Das API bildet die Programmierschnittstelle für die Anwendung: die Funktionen und Variablen, die DBI Perl-Skripten zur Verfügung stellen. Dieses API wird durch die Perl-Erweiterung DBI implementiert.
Der 'Switch' ist der Code, der die einzelnen Aufrufe von DBI-Methoden zur eigentlichen Ausführung an die jeweils richtigen Treiber 'verteilt' (Dispatching). Der Switch ist außerdem für das dynamische Laden von Treibern, die Prüfung und Behandlung von Fehlern und anderen Dingen verantwortlich. Das DBI und der Switch sind generell identisch. (Man kann den Switch guten Gewissens ignorieren. Möglicherweise wird er künftig ganz entfernt.
Die Treiber implementieren die Unterstützung einer bestimmten Datenbank-Engine. Sie enthalten Implementierungen der DBI-Methoden, die mit den Schnittstellenfunktionen der entsprechenden Engine entwickelt wurden. Nur Autoren von anspruchsvollen oder Multi-Datenbankanwendungen oder Entwickler generischer Bibliotheksfunktionen müssen sich mit Treibern beschäftigen.
DBI Statischer 'Top-Level'-Name der Klasse $dbh Datenbankhandle-Objekt $sth Anweisungshandle-Objekt $drh Treiberhandle-Objekt (in Anwendungen selten verwendet) $h Einer der obigen $??h-Handle-Typen $rc Allgemeiner Rückgabewert (boolesch: wahr=OK, falsch=Fehler) $rv Allgemeiner Rückgabewert (üblicherweise ein Integerwert) @ary Liste der von der Datenbank zurückgegebenen Werte, typischerweise eine Reihe von Daten $rows Anzahl der verarbeiteten Datensätze (falls vorhanden, sonst -1) $fh Ein Dateihandle undef NULL-Werte werden bei Perl in Form undefinierter Werte dargestellt
Beachten Sie, daß Perl Datenbank- und Anweisungsobjekte automatisch entfernt, wenn alle Referenzen darauf gelöscht wurden.
Objektattribute für Handles erscheinen wie folgt:
(type)
$h->{attribute_name}
Dabei gibt type den Wertetyp des Attributs an (wenn es sich nicht um einen einfachen Skalarwert handelt):
\$ Referenz auf einen Skalar: $h->{attr} oder $a = ${$h->{attr}}
\@ Referenz auf eine Liste: $h->{attr}->[0] oder @a = @{$h->{attr}}
\% Referenz auf einen Hash: $h->{attr}->{a} oder %a = %{$h->{attr}}
Die meisten Daten werden als Strings an das Perl-Skript zurückgegeben (NULL-Werte erscheinen als undefinierte Werte). Numerische Daten beliebiger Genauigkeit können daher ohne Verlust verarbeitet werden. Denken Sie aber daran, daß Perl möglicherweise nicht mit der gleichen Genauigkeit arbeitet, wenn Sie den String in eine Zahl umwandeln.
Datum und Uhrzeit werden als Zeichenketten zurückgegeben, wobei das der Engine eigene Format erhalten bleibt. Zeitzonen-Effekte hängen von der Engine bzw. dem Treiber ab.
Perl unterstützt Binärdaten in Strings, und das DBI leitet binäre Daten vom und zum Treiber ohne Änderungen weiter. Es bleibt den Treiber-Entwicklern überlassen zu entscheiden, wie solche Binärdaten zu behandeln sind.
Mehrere SQL-Anweisungen dürfen nicht in einem einzelnen Anweisungshandle, also einem einzelnen $sth, kombiniert werden.
Nicht-sequentielle Leseoperationen (Fetch-Operationen) auf Records werden von dieser DBI-Version nicht unterstützt. Das bedeutet, daß Records nur in der Reihenfolge gelesen werden können, in der sie von der Datenbank zurückgegeben werden. Zudem werden sie nach dem Fetch sofort wieder vergessen.
Positionierte Update- und Löschoperationen werden vom DBI nicht direkt unterstützt. Eine Alternative finden Sie bei der Beschreibung des CursorName-Attributes.
Treiber-Entwicklern steht es frei, beliebige private Funktionen und/oder Handle-Attribute zur Verfügung zu stellen, die sie für sinnvoll halten. Private Treiberfunktionen können mit der DBI-Methode func aufgerufen werden. Auf private Treiberattribute wird genauso zugegriffen wie auf Standardattribute.
Zeichensätze: Die meisten Datenbanken, die mit Zeichensätzen umgehen können, besitzen einen globalen Standardzeichensatz. In der Datenbank abgelegter Text wird, oder sollte zumindest, diesen Zeichensatz verwenden (wenn nicht, liegt der Fehler entweder in der Datenbank oder in der Anwendung, die die Daten geschrieben hat). Beim Einlesen von Text sollte dieser (automatisch) in den Zeichensatz des Clients umgewandelt werden (was vermutlich auf Locale basiert). Benötigt der Treiber ein Flag, um dieses Verhalten zu erzielen, sollte der Treiber es entsprechend setzen. Diese Aufgabe sollte nicht der Anwendung überlassen bleiben.
Die für Attributnamen verwendete Schreibweise ist von Bedeutung und spielt eine wichtige Rolle bei der Portabilität von DBI-Skripten. Die Schreibweise der Attributnamen macht deutlich, wer die Bedeutung des Namens und seine Werte definiert hat.
Schreibweise Bedeutung definiert durch ------------ ------------------------- GROSS Standards, z.B. X/Open, SQL92 etc. (portabel) Gemischt DBI-API (portabel), Unterstriche werden nicht verwendet. klein Treiber- bzw. Engine-spezifisch (nicht portabel)
Es ist von äußerster Wichtigkeit, daß Entwickler von Treibern bei der Definition privater Attribute nur mit Kleinschreibung arbeiten. Private Attributnamen müssen den Treibernamen oder eine passende Abkürzung (z.B. ora_ für Oracle, ing_ für Ingres etc.) als Präfix verwenden.
Hier ist eine typische Methoden-Aufrufsequenz für eine select-Anweisung:
connect, prepare, execute, fetch, fetch, ... finish, execute, fetch, fetch, ... finish, execute, fetch, fetch, ... finish.
Hier ist eine typische Methoden-Aufrufsequenz für eine Nicht-select-Anweisung:
connect,
prepare,
execute,
execute,
execute.
insert into sales (product_code, qty, price) values (?, ?, ?)
Um die Beschreibung eines Produktes zu wählen, könnte wie folgt vorgegangen werden:
select product_description from products where product_code = ?
Die ?-Zeichen sind die Platzhalter. Die Verknüpfung tatsächlicher Werte mit Platzhaltern wird als Bindung bezeichnet, und die entsprechenden Werte werden Bindungswerte genannt. Nullwerte können mit undefinierten Werten oder mit undef übergeben werden.
Ohne Platzhalter müßte die obige INSERT-Anweisung die literalen Werte enthalten und man müßte für jeden Datensatz die Methoden prepare und execute neu aufrufen. Mit Hilfe der Platzhalter genügt ein einmaliges prepare und nur das execute wird wiederholt, wobei die Parameter übergeben werden. Das ist oft erheblich schneller.
my $sth = $dbh->prepare(q{
insert into sales (product_code, qty, price) values (?, ?, ?)
}) || die $dbh->errstr;
while(<>) {
chop;
my($product_code, $qty, $price) = split(/,/);
$sth->execute($product_code, $qty, $price) || die $dbh->errstr;
}
$dbh->commit || die $dbh->errstr;
Details finden Sie unter execute und bind_param.
Verwandte Methoden, die Perl-Variablen mit den Ausgabe-Spalten einer select-Anweisung verknüpfen, finden Sie unter bind_column.
http://www.jcc.com/sql_stnd.html http://w3.one.net/~jhoffman/sqltut.htm http://skpc10.rdg.ac.uk/misc/sqltut.htm http://epoch.CS.Berkeley.EDU:8000/sequoia/dba/montage/FAQ/SQL_TOC.html http://www.bf.rmit.edu.au/Oracle/sql.html
DBI selbst gibt weder eine bestimmte Sprache vor, noch verlangt es eine. In ODBC-Begriffen ausgedrückt, befindet sich DBI immer im Pass-Thru-Modus. Verlangt wird nur, daß Queries und andere Anweisungen in einem einzelnen String ausgedrückt werden müssen. Dieser String wird als erstes Argument an die prepare-Methode übergeben.
$dbh = DBI->connect($data_source, $username, $password); $dbh = DBI->connect($data_source, $username, $password, \%attr);
Baut eine Datenbankverbindung (Session) mit der angeforderten Datenquelle (data_source) auf. Gibt ein Datenbankhandle-Objekt zurück.
Mehrere simultane Verbindungen zu mehreren Datenbanken über mehrere Treiber sind mit DBI möglich. Rufen Sie connect einfach für jede Datenbank auf, und nutzen Sie das zurückgegebene Datenbankhandle.
Der Wert für $data_source muß mit 'dbi:driver_name:' beginnen.
Das Präfix wird entfernt, und der verbleibende driver_name-Teil wird zur
Bestimmung des Treibers benutzt (die Groß-/Kleinschreibung ist relevant).
Ist das $data_source-Feld undefiniert oder leer, fügt DBI den
Wert der Umgebungsvariable DBI_DSN ein (falls vorhanden).
Wird kein Treiber angegeben, wird auf die Umgebungsvariable DBI_DRIVER zurückgegriffen. Ist diese Variable nicht gesetzt, wird der connect-Versuch abgebrochen ('die').
Beispiele für $data_source-Werte:
dbi:DriverName:database_name dbi:DriverName:database_name@hostname dbi:DriverName:database_name~hostname!port dbi:DriverName:database=database_name;host=hostname;port=port
Es gibt keinen Standard für den auf den Treibernamen folgenden Text. Jedem Treiber steht es frei, eine beliebige Syntax zu verwenden. DBI verlangt nur, daß alle Informationen in einem einzelnen String enthalten sind. Sie müssen die Dokumentation des von Ihnen verwendeten Treibers konsultieren, um an eine Beschreibung der erforderlichen Syntax zu gelangen. Muß ein Treiber-Autor eine Syntax für die Datenquelle definieren, so wird empfohlen, sich an den ODBC-Stil (die letzte Variante im obigen Beispiel) zu halten.
Sind $username oder $password undefiniert (statt leer), setzt DBI die Werte der Umgebungsvariablen DBI_USER bzw. DBI_PASS ein. Die Verwendung von Umgebungsvariablen für diese Werte wird aus Sicherheitsgründen aber nicht empfohlen. Der Mechanismus ist nur dazu gedacht, das Testen zu vereinfachen.
DBI->connect lädt den Treiber automatisch, falls das bislang noch nicht geschehen ist. Das Laden eines Treibers liefert immer ein gültiges Treiberhandle zurück oder führt zu einem die, dessen Fehlermeldung den String 'install_driver' und das zugrundeliegende Problem enthält. DBI->connect bricht bei einem Fehler während des Ladens des Treibers also mit die ab und gibt undef nur bei einem connect-Fehler zurück, für den $DBI::errstr die Fehlermeldung enthält.
Das $data_source-Argument (ohne das 'dbi:...:'-Präfix) sowie die $username- und $password-Argumente werden dann dem Treiber zur Verarbeitung übergeben. DBI definiert keinerlei Interpretation des Inhalts dieser Felder. Dem Treiber steht es frei, die Felder data_source, username und password in jeder gewünschten Weise zu interpretieren und beliebige Standardwerte einzusetzen, die für die jeweilige Engine sinnvoll sind. (Zum Beispiel verwendet Oracle die Umgebungsvariablen ORACLE_SID und TWO_TASK, wenn data_source nicht angegeben wird.)
Die AutoCommit- und PrintError-Attribute sind bei jeder Verbindung standardmäßig an (weitere Informationen finden Sie unter AutoCommit und PrintError).
Der \%attr-Parameter kann verwendet werden, um die Standardeinstellungen der PrintError-, RaiseError- und AutoCommit-Attribute zu ändern:
$dbh = DBI->connect($data_source, $user, $pass, {
PrintError => 0,
AutoCommit => 0
});
Das ist augenblicklich die einzige definierte Verwendung für DBI->connect \%attr.
Portable Anwendungen dürfen nicht davon ausgehen, daß ein einzelner Treiber mehrere simultane Sessions unterstützt.
Wo immer möglich, ist jede Session ($dbh) von Transaktionen in anderen Sessions unabhängig. Das ist nützlich, wenn Sie Cursor über Transaktionen hinweg offenhalten müssen, z.B., wenn Sie eine Session für den langlebigen Cursor (üblicherweise mit reinen Leserechten) und eine andere für Ihre kurzen Update-Transaktionen verwenden.
Um mit alten DBI-Skripten kompatibel zu sein, kann der Treiber durch Angabe seines Namens als viertes Argument des connect-Aufrufs (anstelle von \%attr) übergeben werden:
$dbh = DBI->connect($data_source, $user, $pass, $driver);
Bei dieser 'alten' Form des connect-Aufrufs sollte $data_source nicht mit 'dbi:driver_name:' beginnen. Ist das doch der Fall, wird der eingebettete driver_name ignoriert. Das $dbh->{AutoCommit}-Attribut ist undefiniert. Das $dbh->{PrintError}-Attribut ist nicht gesetzt. Außerdem wird die alte Umgebungsvariable DBI_DBNAME berücksichtigt, wenn DBI_DSN nicht definiert ist.
@ary = DBI->available_drivers; @ary = DBI->available_drivers($quiet);
Gibt eine Liste aller verfügbaren Treiber zurück. Hierzu werden alle Verzeichnisse in @INC nach DBD::*-Modulen durchsucht. Per Voreinstellung wird eine Warnung ausgegeben, wenn einige Treiber durch andere Treiber gleichen Namens in früheren Verzeichnissen verdeckt werden. Die Übergabe eines Wahr-Wertes für $quiet unterdrückt diese Warnung.
@ary = DBI->data_sources($driver);
Gibt eine Liste aller Datenquellen (Datenbanken) zurück, die durch den benannten Treiber zugänglich sind. Der Treiber wird geladen, falls er es noch nicht ist. Ist $driver leer oder undefiniert, wird der Wert der Umgebungsvariablen DBI_DRIVER verwendet.
Beachten Sie, daß viele Treiber keine Möglichkeit besitzen, herauszufinden, welche Datenquellen verfügbar sind, und daher (üblicherweise) eine leere Liste zurückliefern.
DBI->trace($trace_level) DBI->trace($trace_level, $trace_file)
DBI-Tracing-Informationen können für alle Handles mit Hilfe dieser DBI-Klassenmethode aktiviert werden. Um Tracing-Daten zu einem bestimmten Handle zu sammeln, verwenden Sie die an anderer Stelle beschriebene $h->trace-Methode.
Verwenden Sie den $trace_level 2, um detaillierte Aufruf-Traces einschließlich aller Parameter und Rückgabewerte zu generieren. Die Trace-Ausgabe ist detailliert und üblicherweise sehr nützlich.
Mit dem $trace_level 0 deaktivieren Sie das Tracing.
Ist $trace_filename vorhanden, wird die entsprechende Datei geöffnet, und alle Trace-Ausgaben (auch die anderer Handles) werden an diese Datei angehängt.
Unter $h->trace() und im Abschnitt "Debugging" finden Sie auch Informationen zur Umgebungsvariablen DBI_TRACE.
$str = DBI::neat($value, $maxlen);
Liefert einen String zurück, der eine "ordentliche" Darstellung des angegebenen Wertes enthält.
Strings werden mit Quoting-Zeichen versehen (wobei interne Quoting-Zeichen aber nicht zusätzlich geschützt werden). Bei numerischen Werten werden Quoting-Zeichen üblicherweise entfernt. Undefinierte (NULL-)Werte erscheinen als undef (ohne Quoting). Nicht druckbare Zeichen werden durch einen Punkt (.) ersetzt. Ist der resultierende String länger als $maxlen (0 oder undef werden durch den Standardwert von 400 Zeichen ersetzt), wird er auf $maxlen-4 Zeichen gekürzt, und ...' wird angehängt.
Diese Funktion dient der Aufbereitung von Werten für uns Menschen. Sie wird DBI-intern für die trace-Ausgabe verwendet. Sie sollte normalerweise nicht benutzt werden, um Werte für Datenbanken aufzubereiten.
$str = DBI::neat_list(\@listref, $maxlen, $field_sep);
Ruft DBI::neat für jedes Element der Liste auf und gibt einen String zurück, der die durch $field_sep getrennten Ergebnisse enthält. $field_sep ist mit ", " voreingestellt.
$rows = DBI::dump_results($sth, $maxlen, $lsep, $fsep, $fh);
Liest alle Datensätze aus $sth ein, ruft DBI::neat_list für jeden Datensatz auf und gibt die Ergebnisse über $fh (standardmäßig STDOUT) aus. Dabei wird jede Zeile durch $lsep (standardmäßig "\n") getrennt. $fsep ist mit ", " und $maxlen mit 35 voreingestellt.
Diese Funktion wurde als nützliches Utility zum Prototyping und Testen von Queries konzipiert. Da es neat_list nutzt, das wiederum neat verwendet, um den String für uns Menschen aufzubereiten, ist es für Datenübertragungsanwendungen nicht empfehlenswert.
Wo ein Attribut mit einem Methodenaufruf identisch ist, sei auf den Methodenaufruf für die entsprechende Dokumentation verwiesen.
Warnung: Diese Attribute stehen der Bequemlichkeit halber zur Verfügung, haben aber auch ihre Grenzen. Insbesondere weil sie mit dem zuletzt verwendeten Handle verknüpft sind, sollten sie nur unmittelbar nach dem Aufruf der Methode verwendet werden, die sie 'gesetzt' hat. (Sie haben nur eine 'kurze Lebenserwartung'.) Es kann auch Probleme mit dem Multithreading unter 5.005 geben.
Beim geringsten Zweifel sollten Sie den entsprechenden Methodenaufruf verwenden.
$rv = $h->err;
Gibt den datenbankeigenen Fehlercode für die zuletzt aufgerufene Treiberfunktion zurück.
$str = $h->errstr;
Gibt die datenbankeigene Fehlermeldung für die zuletzt aufgerufene Treiberfunktion zurück.
$str = $h->state;
Gibt einen Fehlercode im Standard-SQLSTATE-Format (fünf Zeichen) zurück. Beachten Sie, daß der 'Success'-Code 00000 zu 0 (falsch) umgewandelt wird. Wird SQLSTATE von Ihrem Treiber nicht unterstützt, gibt state bei allen Fehlern S1000 (Allgemeiner Fehler) zurück.
$h->trace($trace_level); $h->trace($trace_level, $trace_filename);
Tracing-Informationen können bei DBI für ein bestimmtes Handle (und alle zukünftigen Children des Handles) aktiviert werden, indem man den Trace-Level mit Hilfe der Trace-Methode einstellt.
Verwenden Sie den $trace_level 2, um detaillierte Aufruf-Traces einschließlich aller Parameter und Rückgabewerte zu generieren. Die Trace-Ausgabe ist detailliert und üblicherweise sehr nützlich.
Mit dem $trace_level 0 deaktivieren Sie das Tracing.
Ist $trace_filename vorhanden, wird die entsprechende Datei geöffnet, und alle Trace-Ausgaben (auch die anderer Handles) werden an diese Datei angehängt.
Unter $h->trace() und im Abschnitt "Debugging" finden Sie auch Informationen zur Umgebungsvariablen DBI_TRACE.
$h->func(@func_arguments, $func_name);
Die func-Methode kann verwendet werden, um durch den Treiber implementierte private, Nicht-Standard- und nicht-portable Methoden aufzurufen. Beachten Sie, daß der Funktionsname als letztes Argument angegeben wird.
Diese Methode hat nichts mit dem Aufruf gespeicherter Prozeduren zu tun. Der Aufruf gespeicherter Prozeduren ist bei DBI momentan nicht definiert. Einige Treiber, wie etwa DBD::Oracle, unterstützen diese Aufrufe in nicht-portabler Form. Details finden Sie in der Treiberdokumentation.
Einige Attribute werden von Child-Handles geerbt, d.h., der Wert eines geerbten Attributs in einem neu angelegten Anweisungshandle entspricht dem Wert im Parent-Datenbankhandle. Änderungen der Attribute in diesem neuen Anweisungshandle haben keinen Einfluß auf das Parent-Datenbankhandle. Gleichzeitig haben Änderungen im Datenbankhandle keinen Einfluß auf existierende Anweisungshandles, sondern nur auf zukünftige Handles.
Der Versuch, den Wert eines unbekannten Attributs zu setzen oder zu lesen, ist fatal, es sei denn bei privaten, treiberspezifischen Attributen (deren Namen immer klein geschrieben werden).
Beispiel:
$h->{AttributeName} = ...; # setzen/schreiben
... = $h->{AttributeName}; # lesen
warn("$DBI::errstr"). Beachten Sie, daß der Inhalt der Warnung momentan einfach nur aus $DBI::errstr besteht, was sich aber ändern könnte, d.h., Sie dürfen sich nicht darauf verlassen.
Standardmäßig schaltet DBI->connect PrintError ein. (Es sei denn, Sie verwenden die alte connect-Form. Details hierzu finden Sie unter connect.)
Bei Bedarf können die Warnungen abgefangen und über einen $SIG{__WARN__}-Handler oder über Module wie CGI::ErrorWrap verarbeitet werden.
croak("$DBI::errstr").
Ist PrintError ebenfalls aktiv, wird PrintError vor RaiseError ausgeführt - es sei denn, ein __DIE__-Handler wurde definiert. In diesem Fall wird PrintError übergangen, weil croak die Meldung ausgibt.
Beachten Sie, daß der Inhalt von $@ momentan einfach nur aus $DBI::errstr besteht, was sich aber ändern könnte, d.h., Sie dürfen sich nicht darauf verlassen. (Enthält ab Version 1.0x Namen und Zeilennummer der Datei, in der der Fehler auftrat. - Anm. d. Ü:.)
Voreingestellt ist falsch (was sich aber möglicherweise ändern wird). Anwendungen, die ein bestimmtes Verhalten verlangen, sollten das Attribut wie benötigt setzen. Emulationsschnittstellen sollten das Attribut so setzen, daß es dem Verhalten der emulierten Schnittstelle entspricht.
Treiber müssen dieses Attribut nicht unterstützen, müssen aber dafür sorgen, daß undef als Attributwert zurückgegeben wird.
Voreingestellt ist üblicherweise 0 (null) Bytes, was aber zwischen den Treibern variieren kann. Die meisten mit long-Feldern arbeitenden Anwendungen setzen diesen Wert etwas höher als den größten einzulesenden long-Wert.
Den LongReadLen-Wert für ein Anweisungshandle zu ändern, nachdem prepare() aufgerufen wurde, hat normalerweise keine Wirkung mehr. Deshalb ist es üblich, LongReadLen für $dbh zu setzen, bevor die Vorbereitung erfolgt.
Das LongReadLen-Attribut ist nur an das Lesen von long-Werten gekoppelt, nicht an das Einfügen/Aktualisieren.
Wie zu langer Text abgeschnitten wird, legen Sie mit LongTruncOk fest.
Per Voreinstellung ist LongTruncOk falsch, was dazu führt, daß das Einlesen eines abgeschnittenen long-Wertes fehlschlägt. (Anwendungen sollten nach einer Leseschleife immer auf Fehler untersuchen, weil im Falle eines Fehlers, etwa einer Division durch Null oder dem Abschneiden eines long-Feldes, die Fetch-Operation vorzeitig abgebrochen wird.)
Schlägt eine Fetch-Operation aufgrund eines abgeschnittenen long-Feldes und eines falschen LongTruncOk-Wertes fehl, erlauben viele Treiber das Einlesen weiterer Datensätze.
$sth = $dbh->prepare($statement) || die $dbh->errstr; $sth = $dbh->prepare($statement, \%attr) || die $dbh->errstr;
Bereitet eine einzelne Anweisung für die Ausführung durch die Datenbank-Engine vor und gibt eine Referenz auf ein Anweisungshandle-Objekt zurück. Über dieses Handle können Sie Attribute der Anweisung ermitteln und die execute-Methode aufrufen.
Beachten Sie, daß prepare niemals eine Anweisung ausführen darf, selbst wenn es sich nicht um eine select-Anweisung handelt. Es bereitet die Anweisung nur zur Ausführung vor. (Nachdem das gesagt wurde, können wir zugeben, daß einige Treiber, insbesondere Oracle, Datendefinitionsanweisungen wie create/drop table während der Vorbereitung ausführen. In der Praxis ist das kaum ein Problem.)
Treiber für Engines, die das Konzept der Vorbereitung einer Anweisung nicht kennen, speichern die Anweisung üblicherweise im zurückgelieferten Handle ab und arbeiten sie ab, sobald $sth->execute aufgerufen wird. Solche Treiber sind sehr wahrscheinlich nicht in der Lage, nützliche Informationen über die Anweisung zu liefern (z.B. $sth->{NUM_OF_FIELDS}), bis $sth->execute aufgerufen wird. Portable Anwendungen sollten sich dieses Umstandes bewußt sein.
$sth = $dbh->prepare_cached($statement) || die $dbh->errstr; $sth = $dbh->prepare_cached($statement, \%attr) || die $dbh->errstr;
Wie prepare, nur mit der Ausnahme, daß das
zurückgegebene Anweisungshandle in einem mit $dbh verknüpften Hash abgelegt wird. Wird prepare_cached erneut mit den gleichen Parameterwerten aufgerufen, dann wird der im Cache abgelegte $sth zurückgegeben (ohne daß der Datenbank-Server bemüht wird).
Das Caching kann in einigen Anwendungen sehr nützlich sein, kann aber auch zu Problemen führen und sollte mit besonderer Vorsicht verwendet werden. Momentan wird eine Warnung generiert, wenn das aus dem Cache zurückgegebene $sth aktiv ist (d.h., finish wurde noch nicht aufgerufen).
Der Zugriff auf den Cache (und das Löschen) erfolgt über das CachedKids-Attribut.
$rc = $dbh->do($statement) || die $dbh->errstr; $rc = $dbh->do($statement, \%attr) || die $dbh->errstr; $rv = $dbh->do($statement, \%attr, @bind_values) || ...
Bereitet eine Anweisung vor und führt sie aus. Gibt die Anzahl der betroffenen Felder (-1, falls nicht bekannt oder verfügbar) oder undef bei einem Fehler zurück.
Diese Methode ist normalerweise bei Nicht-select-Anweisungen am nützlichsten, die nicht im voraus vorbereitet werden können (durch eine Einschränkung des Treibers) oder nicht wiederholt ausgeführt werden müssen.
Die Standard-do-Methode ist, was ihre Logik betrifft, identisch mit:
sub do {
my($dbh, $statement, $attr, @bind_values) = @_;
my $sth = $dbh->prepare($statement, $attr) or return undef;
$sth->execute(@bind_values) or return undef;
my $rows = $sth->rows;
($rows == 0) ? "0E0" : $rows;
}
Beispiel:
my $rows_deleted = $dbh->do(q{
delete from table
where status = 'DONE'
}) || die $dbh->errstr;
Die Verwendung von Platzhaltern und @bind_values mit der do-Methode kann sehr nützlich sein, weil man so die Notwendigkeit eines sauberen Quotings aller Variablen im $statement umgehen kann.
$rc = $dbh->commit || die $dbh->errstr;
Permanente Übernahme der letzten Änderungen, wenn die Datenbank Transaktionen unterstützt.
Unterstützt die Datenbank Transaktionen und ist AutoCommit aktiv, sollte commit eine "commit ineffective with AutoCommit"-Warnung ausgeben.
Siehe auch Transaktionen.
$rc = $dbh->rollback || die $dbh->errstr;
Rücknahme (Undo) der letzten Datenbankänderungen (die noch nicht mit commit übernommen wurden), wenn die Datenbank Transaktionen unterstützt.
Unterstützt die Datenbank Transaktionen und ist AutoCommit aktiv, sollte rollback eine "rollback ineffective with AutoCommit"-Warnung ausgeben.
Siehe auch Transaktionen.
$rc = $dbh->disconnect || warn $dbh->errstr;
Koppelt die Datenbank vom Datenbankhandle ab. Wird normalerweise nur vor dem Verlassen des Programms aufgerufen. Das Handle hat nach dem Abkoppeln nur noch geringen Nutzen.
Das Transaktionsverhalten der disconnect-Methode ist (leider) nicht genau definiert. Einige Datenbanksysteme (wie Oracle und Ingres) übernehmen ausstehende Änderungen automatisch (commit), während andere (wie Informix) alle ausstehenden Änderungen zurücknehmen (rollback). Anwendungen sollten also vor einem disconnect explizit commit oder rollback aufrufen.
Die Datenbank wird automatisch abgekoppelt (von der DESTROY-Methode), wenn immer noch eine Verbindung existiert, auch wenn keine Referenzen mehr auf das Handle vorhanden sind. Die DESTROY-Methode jedes Treibers sollte rollback explizit aufrufen, um alle noch nicht mit commit übernommenen Änderungen aufzuheben. Dieses Verhalten ist lebenswichtig, weil es sicherstellt, daß unvollständige Transaktionen nicht übernommen werden, nur weil Perl vor dem Ende DESTROY für jedes Objekt aufruft.
Wenn Sie eine Datenbank abkoppeln, obwohl noch aktive Anweisungshandles vorhanden sind, erhalten Sie eine Warnung. Die Anweisungshandles sollten vor dem Abkoppeln entweder gelöscht oder über die finish-Methode abgearbeitet werden.
$rc = $dbh->ping;
Versucht (in halbwegs effizienter Form) zu bestimmen, ob der Datenbank-Server noch läuft und die Verbindung zu diesem Server immer noch funktioniert.
Die aktuelle Implementierung gibt momentan immer wahr zurück, ohne tatsächlich irgend etwas zu tun. Individuelle Treiber sollten diese Funktion in der für die jeweilige Datenbank geeignetsten Form implementieren.
Nur sehr wenige Anwendungen haben Verwendung für diese Methode. Eine Beispielanwendung finden Sie im Apache::DBI-Modul.
$sql = $dbh->quote($string);
Quoting eines String-Literals für die Nutzung innerhalb einer SQL-Anweisung. Hierzu werden alle besonderen Zeichen im String (wie Anführungszeichen) durch Fluchtsymbole geschützt (Escaping). Gleichzeitig werden die benötigten äußeren Quoting-Zeichen hinzugefügt.
$sql = sprintf "select foo from bar where baz = %s",
$dbh->quote("Don't\n");
Für die meisten Datenbanken würde quote 'Don"t' (einschließlich der äußeren Quoting-Zeichen) zurückgeben.
Ein undefinierter $string-Wert wird als NULL (ohne Quoting-Zeichen) zurückgegeben.
Quote ist möglicherweise nicht in der Lage, mit allen möglichen Eingaben (wie etwa Binärdaten) umzugehen. Sicherheitshalber sollten Sie sich nicht darauf verlassen.
Änderungen dieser Datenbankhandle-Attribute haben keinerlei Einfluß auf andere (existierende oder zukünftige) Datenbankhandles.
Der Versuch, den Wert eines unbekannten Attributes zu setzen oder zu lesen, ist fatal. Ausgenommen sind hier private, treiberspezifische Attribute (deren Namen nur aus Kleinbuchstaben bestehen).
Beispiel:
$h->{AutoCommit} = ...; # schreiben
... = $h->{AutoCommit}; # lesen
Treiber sollten standardmäßig immer den AutoCommit-Modus verwenden. (Eine unglückliche Wahl, die dem DBI durch ODBC- und JDBC-Konventionen auferlegt wurde.)
Der Versuch, AutoCommit auf einen nicht-unterstützten Wert zu setzen, führt
zu einem fatalen Fehler. Das ist ein sehr wichtiges Merkmal von DBI.
Anwendungen, die ein vollständiges Transaktionsverhalten erfordern, können
$dbh->{AutoCommit}=0 setzen (auch über connect), ohne prüfen zu müssen,
ob der Wert richtig zugewiesen wurde. (... sofern man einen andernfalls erfolgenden Abbruch des Programms für sinnvoll hält. Eher empfehlenswert ist eval { $dbh->{AutoCommit} = 0 }; if ($@) { print "Keine Transaktionen" } - Anm. d. Ü.)
Zum Zweck der Erläuterung können wir Datenbanken in drei Kategorien unterteilen:
Datenbanken, die überhaupt keine Transaktionen unterstützen.
Datenbanken, bei denen eine Transaktion immer aktiv ist.
Datenbanken, bei denen eine Transaktion explizit gestartet werden muß ('BEGIN WORK').
* Datenbanken, die überhaupt keine Transaktionen unterstützen
Bei diesen Datenbanken führt der Versuch, AutoCommit auszuschalten, zu einem fatalen Fehler. Commit und rollback geben beide die Warnung aus, daß sie keinerlei Effekt haben, solange AutoCommit aktiv ist.
* Datenbanken, bei denen eine Transaktion immer aktiv ist
Die typischen, weit verbreiteten, kommerziellen relationalen Datenbanken mit einem dem 'ANSI-Standard' entsprechenden Transaktionsverhalten.
Bei deaktiviertem AutoCommit spiegeln sich Änderungen in der Datenbank nirgendwo wider, bis commit aufgerufen wird (denken Sie aber auch an disconnect). Wird rollback aufgerufen, werden alle Änderungen verworfen, die nach dem letzten commit vorgenommen wurden.
Bei aktiviertem AutoCommit haben wir den gleichen Effekt, als würde DBI nach jeder erfolgreichen Datenbankoperation automatisch commit aufrufen. Mit anderen Worten, ist der explizite Aufruf von commit oder rollback bei aktivem AutoCommit völlig ohne Wirkung, weil die Änderungen bereits übernommen wurden.
Der Wechsel des AutoCommit-Wertes von 'aus' auf 'an' sollte bei den meisten Treibern zu einem commit führen.
Der Wechsel des AutoCommit-Wertes von 'an' auf 'aus' sollte keinen unmittelbaren Effekt haben.
Bei Datenbanken, die keinen bestimmten AutoCommit-Modus unterstützen, muß der Treiber nach jeder erfolgreichen Anweisung automatisch ein explizites COMMIT hinterherschicken (oder ein explizites ROLLBACK, wenn die Operation fehlgeschlagen ist). Die an die Anwendung gemeldeten Fehlerinformationen gehören zu der ausgeführten Anweisung - es sei denn, diese war erfolgreich und commit oder rollback sind fehlgeschlagen.
* Datenbanken, bei denen eine Transaktion explizit gestartet werden muß
Bei diesen Datenbanken wird die Absicht verfolgt, sie so handeln zu lassen wie Datenbanken, bei denen eine Transaktion (wie oben beschrieben) immer aktiv ist.
Um dies zu erreichen, startet der DBI-Treiber automatisch eine Transaktion, sobald AutoCommit ausgeschaltet wird (aus seinem standardmäßig aktiven Zustand). Eine weitere Transaktion wird automatisch gestartet, nachdem ein commit oder rollback abgesetzt wurde.
Auf diese Weise muß die Anwendung diese Datenbanken nicht als Sonderfälle behandeln.
$rc = $sth->bind_param($param_num, $bind_value) || die $sth->errstr; $rv = $sth->bind_param($param_num, $bind_value, \%attr) || ... $rv = $sth->bind_param($param_num, $bind_value, $bind_type) || ...
Mit der Methode bind_param können Sie einen Wert an einen Platzhalter binden (zuweisen/verknüpfen), der in einer vorbereiteten Anweisung eingebettet ist. Platzhalter werden durch ein Fragezeichen (?) angezeigt. Hier ein Beispiel:
$dbh->{RaiseError} = 1; # Prüfung jedes einzelnen Methodenaufrufs vermeiden
$sth = $dbh->prepare("select name, age from people where name like ?");
$sth->bind_param(1, "John%"); # Die Numerierung von Platzhaltern beginnt bei 1
$sth->execute;
DBI::dump_results($sth);
Beachten Sie, daß ? nicht in Quoting-Zeichen steht, auch wenn der Platzhalter einen String repräsentiert. Einige Treiber erlauben neben dem ? auch Platzhalter der Form :1, :2 und :name. Ihre Verwendung ist aber nicht portabel.
Einige Treiber unterstützen keine Platzhalter.
Bei den meisten Treibern können Platzhalter für bestimmte Elemente nicht verwendet werden. Das ist bei Elementen der Fall, bei denen der Datenbank-Server die Anweisung nicht mehr überprüfen kann oder keinen Query-Ausführungsplan erzeugt. Beispiele:
"select name, age from ?" # falsch "select name, ? from people" # falsch
Auch können Platzhalter nur einzelne Skalarwerte darstellen, weshalb beispielsweise die folgende Anweisung bei mehr als einem Wert nicht wie erwartet funktionieren würde:
"select name, age from people where name in (?)" # falsch
Der \%attr-Parameter kann genutzt werden, um den Datentyp festzulegen, den der Platzhalter besitzen sollte. Normalerweise will der Treiber nur wissen, ob der Platzhalter an eine Zahl oder einen String gebunden ist.
$sth->bind_param(1, $value, { TYPE => SQL_INTEGER });
Als Abkürzung dieses üblichen Falles kann der Datentyp direkt anstelle der attr-Hashreferenz übergeben werden. Das folgende Beispiel ist daher mit dem obigen identisch:
$sth->bind_param(1, $value, SQL_INTEGER);
TYPE kann nach dem ersten Aufruf von bind_param nicht mehr geändert werden (braucht aber auch nicht angegeben zu werden, wobei dann auf den vorherigen Wert zurückgegriffen wird).
Perl kennt als skalare Datentypen nur Strings und Zahlen. Alle Datenbanktypen, bei denen es sich nicht um Zahlen handelt, werden zu Strings gebunden und müssen in einem Format vorliegen, das die Datenbank verarbeiten kann.
Undefinierte Werte oder undef werden für Nullwerte verwendet.
$rc = $sth->bind_param_inout($param_num, \$bind_value, $max_len) || die $sth->errstr; $rv = $sth->bind_param_inout($param_num, \$bind_value, $max_len, \%attr) || ... $rv = $sth->bind_param_inout($param_num, \$bind_value, $max_len, $bind_type) || ...
Diese Methode arbeitet wie bind_param, aktiviert gleichzeitig aber die Werte, die von der Anweisung ausgegeben (aktualisiert) werden. (Die Anweisung ist üblicherweise ein Aufruf einer gespeicherten Prozedur.) $bind_value muß als Referenz auf den eigentlich zu verwendenden Wert übergeben werden.
Der zusätzliche Parameter $max_len gibt an, wieviel Speicher für den neuen Wert an $bind_value bereitzustellen ist. Momentan ist nicht definiert, wie der Wert abgeschnitten wird, wenn er länger als $max_len ist.
Es wird erwartet, daß nur wenige Treiber diese Methode unterstützen. Der einzige momentan bekannte Treiber ist DBD::Oracle. Diese Methode darf nicht für datenbankunabhängige Anwendungen verwendet werden.
$rv = $sth->execute || die $sth->errstr; $rv = $sth->execute(@bind_values) || die $sth->errstr;
Führt alle erforderlichen Arbeiten durch, die zur Ausführung der vorbereiteten Anweisung notwendig sind. Bei einem Fehler wird undef zurückgegeben, die erfolgreiche Ausführung gibt hingegen immer wahr (siehe unten) zurück. Es ist immer wichtig, den Rückgabestatus von execute (und der meisten anderen DBI-Methoden) zu prüfen.
Bei einer Nicht-select-Anweisung gibt execute die Anzahl der betroffenen Felder (falls bekannt) zurück. Null wird als "0E0" zurückgegeben, was Perl als 0, gleichzeitig aber auch als wahr, betrachtet. Ist die Anzahl der betroffenen Felder nicht bekannt, gibt execute -1 zurück.
Bei select-Anweisungen 'startet' execute die Query einfach innerhalb der Engine. Verwenden Sie eine der fetch-Methoden, um nach dem Aufruf von execute an die Daten zu gelangen. Die execute-Methode gibt nicht die Anzahl der Datensätze zurück, die von der Query zurückgegeben werden (weil die meisten Engines das im voraus nicht sagen können), sondern einfach den Wert wahr.
Werden irgendwelche Argumente übergeben, ruft execute für jeden Wert bind_param auf, bevor die Anweisung ausgeführt wird. Auf diese Weise gebundene Werte werden üblicherweise als SQL_VARCHAR-Typen betrachtet, es sei denn, der Treiber kann den richtigen Typ bestimmen (was selten ist) oder bind_param (oder bind_param_inout) wurde bereits benutzt, um den Typ festzulegen.
$ary_ref = $sth->fetchrow_arrayref; $ary_ref = $sth->fetch; # Alias
Liest den nächsten Datensatz ein und gibt eine Referenz auf ein Array zurück, das die Feldwerte enthält. Sind keine weiteren Datensätze vorhanden, gibt fetchrow_arrayref undef zurück. Nullwerte werden als undef zurückgegeben. Das ist der schnellste Weg zum Einlesen von Daten, insbesondere, wenn es zusammen mit $sth->bind_columns verwendet wird.
Beachten Sie, daß für jeden Fetch die gleiche Arrayreferenz zurückgegeben wird. Speichern Sie die Referenz also nicht ab, und greifen Sie nach einem späteren Fetch nicht erneut darauf zu.
(Man kann natürlich das Array kopieren, etwa so:
my @rows;
while (my $ref = $dbh->fetchrow_arrayref()) {
push(@rows, [@$ref]);
}
- Anm. d. Ü.)
@ary = $sth->fetchrow_array;
Eine Alternative zu fetchrow_arrayref. Liest den nächsten Datensatz ein und gibt ein die Feldwerte enthaltendes Array zurück. Liegen keine weiteren Datensätze vor, gibt fetchrow_array eine leere Liste zurück. Nullwerte werden als undef zurückgegeben.
$hash_ref = $sth->fetchrow_hashref;
Eine Alternative zu fetchrow_arrayref. Liest den nächsten Datensatz ein und gibt ihn als Referenz auf einen Hash zurück, der aus Feldname/Feldwert-Paaren besteht. Nullwerte werden als undef zurückgegeben. Liegen keine weiteren Datensätze mehr vor, wird undef zurückgegeben.
Die Schlüssel des Hashes haben die gleichen Namen, wie sie $sth->{NAME} zurückgibt. Haben mehrere Felder den gleichen Namen, wird nur ein Eintrag im Hash zurückgegeben. (Wie bei fetchrow_arrayref wird immer dieselbe Referenz zurückgegeben, die man evtl. mit {%$ref} kopieren muß. - Anm. d. Ü.)
Aufgrund der zusätzlichen Arbeit, die fetchrow_hashref und perl erledigen müssen, ist diese Variante nicht so effizient wie fetchrow_arrayref oder fetchrow_array. Sie wird augenblicklich nicht empfohlen, wenn die Performanz sehr wichtig ist. Das ändert sich möglicherweise in der Zukunft, also verlassen Sie sich nicht darauf.
$tbl_ary_ref = $sth->fetchall_arrayref;
Die fetchall_arrayref-Methode kann verwendet werden, um alle durch eine vorbereitete Anweisung zurückgelieferten Daten einzulesen. Sie gibt eine Referenz auf ein Array zurück, das jeweils eine Arrayreferenz pro Datensatz (wie von fetchrow_arrayref zurückgegeben) enthält.
Sind keine Datensätze vorhanden, gibt fetchall_arrayref eine Referenz auf ein leeres Array zurück.
$rc = $sth->finish;
Gibt an, daß keine weiteren Daten mehr von dieser Anweisung eingelesen werden, bevor sie nicht entweder erneut vorbereitet oder ganz entfernt wird. Der Aufruf dieser Methode kann an bestimmten Stellen nützlich sein, damit der Server alle gerade gehaltenen internen Ressourcen (wie etwa Lese-Locks) freigeben kann. Die Methode hat keinen Einfluß auf den Transaktionsstatus der Session.
Die finish-Methode hat nichts mit Transaktionen zu tun. Sie ist eher eine interne Verwaltungsmethode. Es ist nicht notwendig, finish aufzurufen, wenn Sie das Anweisungshandle entfernen oder wiederverwenden. Siehe auch disconnect.
$rv = $sth->rows;
Gibt die Anzahl der Datensätze zurück, die vom letzten Datenbank-Modifikationsbefehl betroffen waren. Ist die Anzahl nicht bekannt oder nicht verfügbar, wird -1 zurückgegeben.
Generell können Sie sich auf diesen Datensatzzähler nur verlassen, nachdem ein do oder ein nicht-select-execute (bei bestimmten Operationen wie update oder delete) ausgeführt wurde oder nachdem alle Datensätze einer select-Anweisung eingelesen wurden.
Bei select-Anweisungen ist es generell nicht möglich zu wissen, wieviele Datensätze zurückgegeben werden - es sei denn, man liest alle ein. Einige Treiber geben die Anzahl der bislang eingelesenen Datensätze zurück, während andere -1 zurückliefern, bis alle Datensätze eingelesen wurden.
$rc = $sth->bind_col($column_number, \$var_to_bind); $rc = $sth->bind_col($column_number, \$var_to_bind, \%attr);
Bindet eine Ausgabespalte (ein Feld) einer select-Anweisung an eine Perl-Variable. Bei jeder Fetch-Operation aus der Datenbank wird die entsprechende Perl-Variable automatisch aktualisiert. Es ist nicht notwendig, die Werte manuell einzulesen und zuzuweisen. Das macht die Verwendung gebundener Variablen sehr effizient. Ein entsprechendes Beispiel finden Sie unter bind_columns. Beachten Sie, daß die Numerierung der Felder bei 1 beginnt.
Die Bindung erfolgt auf einem sehr niedrigen Level, bei dem das Perl-Aliasing genutzt wird, d.h., es findet kein zusätzlicher Kopiervorgang statt. Solange der Treiber den korrekten internen DBI-Aufruf verwendet, um an das von fetch zurückgelieferte Array zu gelangen, wird die Feldbindung automatisch unterstützt.
Die Methode bind_param führt eine ähnliche Funktion für Eingabevariablen durch. Weitere Informationen finden Sie im Abschnitt "Platzhalter und Bindungswerte".
$rc = $sth->bind_columns(\%attr, @list_of_refs_to_vars_to_bind);
zum Beispiel
$dbh->{RaiseError} = 1; # Damit nicht jeder Aufruf auf Fehler überprüft werden muß
$sth = $dbh->prepare(q{ select region, sales from sales_by_region });
my($region, $sales);
# Perl-Variable an Felder binden.
$rv = $sth->bind_columns(undef, \$region, \$sales);
# Sie können auch die Perl-Syntax \(...) verwenden (siehe perlref-Doku):
# $sth->bind_columns(undef, \($region, $sales));
# Feldbindung ist der effizienteste Weg zum Einlesen von Daten.
$sth->execute;
while($sth->fetch) {
print "$region: $sales\n";
}
Ruft bind_col für jedes Feld der select-Anweisung auf.
bind_columns bricht über die ab, wenn die Anzahl der
Referenzen nicht mit der Anzahl der Felder übereinstimmt.
Die Änderung dieser Anweisungshandle-Attribute hat keinerlei Einfluß auf andere existierende oder zukünftige Anweisungshandles.
Der Versuch, den Wert eines unbekannten Attributes zu setzen oder zu lesen, ist fatal. Ausgenommen sind hier private, treiberspezifische Attribute (deren Namen mit einem Kleinbuchstaben beginnen).
Ein Beispiel:
... = $h->{NUM_OF_FIELDS}; # lesen
Beachten Sie, daß einige Treiber für einige oder alle Attribute keine gültigen Werte zurückliefern können, bis $sth->execute ausgeführt wurde. (Auch wenn $sth->finish() ausgeführt wurde, oder $sth->fetch_* ein End-of-data gemeldet hat, sollte man diese Attribute nicht mehr verwenden. - Anm. d. Ü.)
print "First column name: $sth->{NAME}->[0]\n";
print "First column may return NULL\n" if $sth->{NULLABLE}->[0];
"where current of ..." nicht unterstützt, wird undef zurückgegeben.
Details zur Verwendung von AutoCommit mit verschiedenen Datenbanktypen finden Sie in AutoCommit.
Dieser Abschnitt ist relevant für Transaktionen unterstützende Datenbanken, bei denen AutoCommit deaktiviert ist.
Die empfohlene Vorgehensweise zur Implementierung robuster Transaktionen in Perl-Anwendungen besteht in der Verwendung von eval { ... } (was im Gegensatz zu eval "..." sehr schnell ist).
eval {
foo(...) # Hier wird viel Arbeit erledigt.
bar(...) # auch Inserts
baz(...) # und Updates
};
if ($@) {
$dbh->rollback;
# Fehler-Cleanup-Code der Anwendung steht hier.
}
else {
$dbh->commit;
}
Der Code in foo() bzw. jeder innerhalb der geschweiften Klammern ausgeführte Code kann wie folgt implementiert werden:
$h->method(@args) || die $h->errstr
Alternativ kann das Attribut $h->{RaiseError} gesetzt werden, was das DBI
bei einem Fehler automatisch zu einem die() veranlaßt, d.h.,
Sie müssen nicht den Rückgabewert jedes Methodenaufrufs überprüfen. Details finden Sie im Abschnitt "RaiseError".
Ein Hauptvorteil des eval-Ansatzes besteht darin, daß die Transaktion sauber zurückgenommen wird (Rollback), wenn ein beliebiger Code in der inneren Anwendung aus irgendeinem Grund über croak oder die abbricht. Der Hauptvorteil eines gesetzten $h->{RaiseError}-Attributs besteht darin, daß alle DBI-Aufrufe automatisch überprüft werden. Beide Techniken werden empfohlen.
Weil Werte dieser Länge üblicherweise nicht im Speicher gehalten werden können, und weil Datenbanken (im Gegensatz zu anderen Datentypen) die Länge des längsten long-Wertes, der von einer select-Anweisung zurückgegeben wird, nicht im voraus bestimmen können, ist hier eine besondere Behandlung notwendig.
In dieser Situation wird der Wert des $h->{LongReadLen}-Attributes verwendet, um zu bestimmen, wieviel Pufferspeicher für solche Felder bereitzustellen ist. Das Attribut $h->{LongTruncOk} legt wiederum fest, wie das System sich verhält, wenn der eingelesene Wert nicht in den Puffer paßt.
my $dbh = DBI->connect("dbi:Oracle:$data_source", $user, $password)
|| die "Connect zu $data_source fehlgeschlagen: $DBI::errstr";
my $sth = $dbh->prepare( q{
SELECT name, phone
FROM mytelbook
}) || die "Anweisung kann nicht vorbereitet werden: $DBI::errstr";
my $rc = $sth->execute
|| die "Anweisung kann nicht ausgeführt werden: $DBI::errstr";
print "Query gibt $sth->{NUM_OF_FIELDS} Felder zurück.\n\n";
print "$sth->{NAME}->[0]: $sth->{NAME}->[1]\n";
while (($name, $phone) = $sth->fetchrow_array) {
print "$name: $phone\n";
}
# Auf Probleme untersuchen, die die Fetch-Operation schon früh beendet haben können
warn $DBI::errstr if $DBI::err;
$sth->finish;
Bei Unix(-nahen)-Systemen mit einer Bourne-ähnlichen Shell ist das sehr einfach mit einem einzelnen Befehl zu bewerkstelligen:
DBI_TRACE=2 perl your_test_script.pl
Hat DBI_TRACE einen alphanumerischen Wert, wird davon ausgegangen, daß es sich um einen Dateinamen handelt. Das Tracing-Level wird auf 2 gesetzt, und die gesamte Tracing-Ausgabe wird an die Datei angehängt.
Siehe auch trace.
Dr Dobb's Journal, November 1996
The Perl Journal, April 1997
http://www.fugue.com/dbi
Mailing-Listen-Archive finden Sie unter:
http://www.rosat.mpe-garching.mpg.de/mailing-lists/PerlDB-Interest/ http://outside.organic.com/mail-archives/dbi-users/ http://www.coe.missouri.edu/~faq/lists/dbi.html
http://www.arcana.co.uk/technologia/perl/DBI/
Andere verwandte Links:
http://www-ccs.cs.umass.edu/db.html http://www.odmg.org/odmg93/updates_dbarry.html http://www.jcc.com/sql_stnd.html ftp://alpha.gnu.ai.mit.edu/gnu/gnusql-0.7b3.tar.gz
perldoc DBI::FAQ ein.
You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.
IT COMES WITHOUT WARRANTY OF ANY KIND.
Kommerzielle Unterstützung für Perl und die DBI-, DBD::Oracle- und Oraperl-Module ist über The Perl Clinic möglich. Details finden Sie unter http://www.perlclinic.com.
Datentypen (ISO-Typen und -Namen sowie ihre Beziehungen) Fehlerbehandlung Data-Dictionary-Methoden Entwicklung einer Testsuite sowie unterstützende Methoden Portabilität blob_read etc.
perldoc DBI::FAQ.
Die Ergebnisse (auf meiner wenig ausgelasteten Sparc 10) des Einlesens von 50000 Datensätzen mit
1 while $csr->fetch;
waren:
ein Feld: 5300 Fetches pro CPU-Sekunde (zirka); zehn Felder: 4000 Fetches pro CPU-Sekunde (zirka)
Natürlich unterscheiden sich die Ergebnisse zwischen den Plattformen, dennoch bekommen Sie ein Gefühl für die momentan theoretisch zu erwartende maximale Performanz. Zum Vergleich ergibt der Code
1 while @row = $csr->fetchrow_array;
(fetchrow_array ist in etwa mit ora_fetch identisch) folgendes:
ein Feld: 3100 Fetches pro CPU-Sekunde (zirka) zehn Felder: 1000 Fetches pro CPU-Sekunde (zirka)
Beachten Sie den Geschwindigkeitsverlust und die noch dramatischeren Auswirkungen zusätzlicher Felder. (Die Felder waren alle ein Zeichen lang. Die Auswirkungen wären bei längeren Strings noch größer.)
Eine leichte Änderung, die mit den eingelesenen Daten auch wirklich etwas _tut_:
while(@row = $csr->fetchrow_array) {
$hash{++$i} = [ @row ];
}
ergibt: zehn Felder: 500 Fetches pro CPU-Sekunde (zirka)
Diese einfache Erweiterung hat die Performanz also *halbiert*. Ich möchte daher folgern, daß die DBI- und DBD::Oracle-Overheads im Vergleich mit Perl-Overheads (und wohl auch Datenbank-Overheads) sehr klein sind. Wenn Sie also glauben, daß DBI oder Ihr Treiber langsam sind, ersetzen Sie Ihre Fetch-Schleife einfach durch:
1 while $csr->fetch;und vergleichen Sie das Ergebnis. Wenn das nicht viel hilft, zeigen Sie mit dem Finger zuerst auf die Datenbank, die Plattform, das Netzwerk etc. Aber seien Sie vorsichtig, bevor Sie mit dem Finger auf das DBI oder den Treiber zeigen.
(Nachdem ich das gesagt habe, habe ich für jeden ein offenes Ohr, der mir zeigen kann, wie das DBI oder die Treiber noch effizienter gemacht werden können.)
http://www.perl.com/perl/faq/idiots-guide.html http://www3.pair.com/webthing/docs/cgi/faqs/cgifaq.shtml http://www.perl.com/perl/faq/perl-cgi-faq.html http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html http://www.boutell.com/faq/ http://www.perl.com/perl/faq/
Allgemeine Probleme und gute Ideen:
Verwenden Sie das CGI::ErrorWrap-Modul. Denken Sie daran, daß viele Umgebungsvariablen bei CGI-Skripten nicht gesetzt sind.
http://perl.apache.org/
"-I.../DBI" zu finden ist, in "-I.../auto/DBI" (wobei ... ein String ohne Leerzeichen ist).
Jeffrey Urlwin
Einzelne Treiber (DBD::*) können durchaus Code zur Datumsverarbeitung enthalten, aber es ist sehr unwahrscheinlich, daß es damit irgendein Jahr-2000-Problem gibt. Dennoch kann eine Anwendung, die DBI und DBD-Treiber verwendet, Probleme mit dem Jahr 2000 haben, wenn sie nicht gut entworfen und geschrieben wurde.
Beachten Sie hierzu auch den Abschnitt "Does Perl have a year 2000 problem?" in der Perl-FAQ:
http://www.perl.com/CPAN/doc/FAQs/FAQ/PerlFAQ.html
Autor: Tim Bunce E-Mail: dbi-users@fugue.com
Autor: Tim Bunce E-Mail: dbi-users@fugue.com
Autor: Henrik Tougaard E-Mail: ht@datani.dk, dbi-users@fugue.com
Autor: Jonathan Leffler E-Mail: johnl@informix.com, dbi-users@fugue.com
Autor: Thomas Wenrich E-Mail: wenrich@site58.ping.at, dbi-users@fugue.com
Autor: Edmund Mergl E-Mail: E.Mergl@bawue.de, dbi-users@fugue.com
Autor: Peter Haworth E-Mail: pmh@edison.ioppublishing.com, dbi-users@fugue.com
Autor: Davide Migliavacca E-Mail: davide.migliavacca@inferentia.it
Carl Declerck <carl@miskatonic.inbe.net> Terry Greenlaw <z50816@mip.mar.lmco.com>
Carl entwickelt ein generisches Proxy-Objektmodul, das in Zukunft die Basis eines DBD::Proxy-Treibers bilden könnte. Terry macht etwas Vergleichbares. (DBI 1.0x enthält die Module DBI::ProxyServer und DBD::Proxy - Anm. d. Ü.)
Hugo van der Sanden <hv@crypt.compulink.co.uk> Stephen Zander <stephen.zander@mckesson.com>
Basiert auf den Beispielen des lex/yacc-Buches von O'Reilly und auf byacc. (Ein einfacher SQL-Parser ist im Modul SQL::Statement enthalten, das wiederum die Grundlage des DBD::CSV-Treibers darstellt. CSV-Dateien sind die beliebteste Methode zum Export von Tabellen in Textdateien und werden etwa von MS Access und MS Excel verwendet. - Anm. d. Ü.)