Name

DBI - Datenbank(-unabhängige)-Schnittstelle für Perl


Übersicht

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;


Hinweis

Diese DBI-Spezifikation entspricht der DBI-Version 0.93 ($Date: 1998/02/13 14:27:16 $).

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.


Letzte Änderungen

Hier ist eine kurze Zusammenfassung der signifikanten, für den Benutzer sichtbaren Änderungen der letzten Versionen. (Wird eine der neueren Versionen nicht aufgeführt, bedeutet das einfach, daß es in dieser Version keine signifikanten, für den Benutzer sichtbaren Änderungen gab.)

DBI 0.92 - 4.2.1998
Caching-Variante $dbh->prepare_cached() von $dbh->prepare eingeführt. Neue Attribute hinzugefügt: Active, Kids, ActiveKids, CachedKids. Unterstützung für 'private_'-Allzweckattribute hinzugefügt.

DBI 0.91 - 10.12.1997
Bug in New-style DBI->connect behoben, wo AutoCommit und PrintError standardmäßig nicht aktiv waren.

DBI 0.86 - 16.7.1997
$h->{LongReadLen}- und $h->{LongTruncOk}-Attribute für LONGs/BLOBs eingeführt. Die Umgebungsvariablen DBI_USER und DBI_PASS eingeführt. Hinweise zur Verwendung finden Sie unter connect. DBI->trace() zum Setzen des globalen Trace-Levels hinzugefügt (ähnlich dem Handle-orientierten $h->trace). Die Umgebungsvariable PERL_DBI_DEBUG in DBI_TRACE umbenannt (der alte Name funktioniert im Augenblick aber noch). Dokumentation aktualisiert, darunter auch die commit-, rollback-, AutoCommit- und Transaktionsabschnitte. Die Methode bind_param sowie execute(@bind_values) in die Dokumentation aufgenommen.

DBI 0.85 - 25.6.1997
Der 'neue' connect (siehe unten) arbeitet nun standardmäßig im AutoCommit-Modus, solange { AutoCommit => 0 } nicht in den connect-Attributen (siehe connect) angegeben wird. Neue Umgebungsvariable DBI_DSN für Standard-connect-Methode eingeführt (ersetzt DBI_DRIVER).

DBI 0.84 - 20.6.1997
$h->{PrintError}-Attribut eingeführt. Ist dieses Attribut wahr, führen alle Fehler zum Aufruf von 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.

DBI 0.83 - 11.6.1997
Neue Syntax für die Angabe von Treibern beim DBI->connect-Parameter data_source eingeführt: DBI->connect( 'dbi:driver:...', $user, $passwd). Die Methode DBI->data_sources sollte nun data_source-Namen mit dem entsprechenden 'dbi:driver:'-Präfix zurückgeben. DBI->connect gibt eine Warnung aus, wenn \%attr zwar wahr, aber keine Hashreferenz ist. Neue fetchrow-Methoden hinzugefügt (fetchrow_array, fetchrow_arrayref und fetchrow_hashref). Die DBI-FAQ von Alligator Descartes in Modulform eingebunden, um ein einfaches Lesen mittels "perldoc DBI::FAQ" zu ermöglichen.


Beschreibung

Perl-DBI ist ein API (Application Programming Interface) für den Datenbankzugriff unter Perl. Das DBI definiert eine Reihe von Funktionen, Variablen und Konventionen, die zusammen eine konsistente Datenbankschnittstelle bilden, die von der tatsächlich verwendeten Datenbank unabhängig ist.

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.


Architektur einer DBI-Anwendung

           |<- 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.


Notation und Konventionen

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:

$h->{attribute_name}
(type)

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}}


Allgemeine Regeln und Einschränkungen der Schnittstelle

Das DBI besitzt kein Konzept einer 'aktuellen Session'. Jede Session besitzt ein Handle-Objekt (d.h. ein $dbh), das von der connect-Methode zurückgegeben wurde. Dieses Handle-Objekt wird zum Aufruf datenbankbezogener Methoden verwendet.

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.


Namenskonventionen und Namensraum

Das DBI-Paket und alle darunter liegenden Pakete (DBI::*) sind für die Verwendung durch DBI reserviert. Mit DBD:: beginnende Paketnamen sind der Verwendung durch DBI-Datenbanktreiber vorbehalten. Alle von DBI oder DBDs verwendeten Umgebungsvariablen beginnen mit 'DBI_' oder 'DBD_'.

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.


Methoden der Datenabfrage

DBI erlaubt es einer Anwendung, eine Anweisung zur späteren Ausführung vorzubereiten ("prepare"). Eine auf diese Weise vorbereitete Anweisung wird über ein Anweisungshandle-Objekt, z.B. $sth, identifiziert.

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.


Platzhalter und Parameter

Einige Treiber unterstützen Platzhalter und Parameter. Diese Treiber erlauben es, daß Datenbankanweisungen Platzhalter enthalten (manchmal auch "parameter marker", also Parameter-Marken, genannt). Diese stehen für Werte, die zu einem späteren Zeitpunkt übergeben werden, bevor die vorbereitete Anweisung ausgeführt wird. Beispielsweise könnte eine Anwendung wie folgt vorgehen, um eine Reihe von Daten in die SALES-Tabelle einzufügen:

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.


SQL - Eine Abfragesprache

Die meisten DBI-Treiber verlangen von den Anwendungen die Verwendung eines SQL-Dialekts (Structured Query Language), um mit der Datenbank-Engine kommunizieren zu können. Die folgenden Links liefern Ihnen möglicherweise nützliche Hinweise zu SQL:

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.


Die DBI-Klasse


DBI-Klassenmethoden

connect
$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.

available_drivers
@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.

data_sources
@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.

trace
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.


DBI-Utility-Funktionen

neat
$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.

neat_list
$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.

dump_results
$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.


Dynamische DBI-Attribute

Diese Attribute sind immer mit dem zuletzt verwendeten Handle verknüpft.

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.

$DBI::err
Identisch mit $h->err.

$DBI::errstr
Identisch mit $h->errstr.

$DBI::state
Identisch mit $h->state.

$DBI::rows
Identisch mit $h->rows.


Allen Handles gemeinsamen Methoden

err
$rv = $h->err;

Gibt den datenbankeigenen Fehlercode für die zuletzt aufgerufene Treiberfunktion zurück.

errstr
$str = $h->errstr;

Gibt die datenbankeigene Fehlermeldung für die zuletzt aufgerufene Treiberfunktion zurück.

state
$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.

trace
$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.

func
$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.


Allen Handles gemeinsamen Attribute

Diese Attribute sind allen Arten von DBI-Handles gemeinsam.

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 (boolean, inherited)
Aktiviert nützliche Warnungen für bestimmte (schlechte) Angewohnheiten. Standardmäßig aktiviert. Einige Emulationsschichten, insbesondere bei Perl-4-Schnittstellen, deaktivieren Warnungen.

Active (boolean, read-only)
Wahr, wenn das Handle-Objekt 'aktiv' ist. Wird in Anwendungen nur selten verwendet. Die genaue Bedeutung von 'aktiv' ist im Moment noch etwas vage. Bei einem Datenbankhandle bedeutet es üblicherweise, daß das Handle mit einer Datenbank verbunden ist ($dbh->disconnect sollte Active ausschalten). Bei einem Anweisungshandle bedeutet es üblicherweise, daß es sich bei dem Handle um ein select handelt, bei dem noch Daten vorhanden sind ($dbh->finish oder das Einlesen aller Daten sollte Active ausschalten).

Kids (integer, read-only)
Bei einem Treiberhandle enthält Kids die Anzahl der momentan vorhandenen Datenbankhandles, die über dieses Treiberhandle erzeugt wurden. Bei einem Datenbankhandle ist Kids die Anzahl der momentan existierenden Anweisungshandles, die über dieses Datenbankhandle erzeugt wurden.

ActiveKids (integer, read-only)
Wie Kids (siehe oben), diesmal aber nur die aktiven Datenbankhandles (siehe oben).

CachedKids (hash ref)
Bei einem Datenbankhandle wird eine Referenz auf den Cache (Hash) der Anweisungshandles zurückgegeben, die mit der prepare_cached-Methode erzeugt wurden. Bei einem Treiberhandle würde es eine Referenz auf den Cache (Hash) der Anweisungshandles zurückgeben, die mit der (noch nicht implementierten) connect_cached-Methode erzeugt worden wären.

CompatMode (boolean, inherited)
Wird von Emulationsschichten (wie Oraperl) verwendet, um für dieses Handle ein kompatibles Verhalten im darunterliegenden Treiber (z.B. DBD::Oracle) zu erzielen. Wird normalerweise nicht innerhalb der Anwendung gesetzt.

InactiveDestroy (boolean)
Dieses Attribut kann verwendet werden, um den Effekt der Löschung eines Handles zu vermeiden (was normalerweise eine vorbereitete Anweisung schließen oder die Verbindung zur Datenbank beenden würde etc.). Wurde speziell für den Einsatz in Unix-Anwendungen entwickelt, bei denen Child-Prozesse mit 'fork' gestartet werden. Entweder der Parent- oder der Child-Prozeß (aber nicht beide) muß InactiveDestroy bei allen Handles setzen. Das Attribut deaktiviert nicht den expliziten Aufruf der disconnect-Methode.

PrintError (boolean, inherited)
Mit diesem Attribut können Sie dafür sorgen, daß bei Fehlern, neben der Rückgabe des üblichen Fehlercodes, Warnungen (über warn) generiert werden. Ist dieses Attribut gesetzt, veranlaßt jeder zu einem Fehler führende Methodenaufruf ($DBI::err ist wahr) DBI zum Aufruf von 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.

RaiseError (boolean, inherited)
Mit diesem Attribut können Sie dafür sorgen, daß Fehler zu Ausnahmen (Exceptions) führen, statt einfach nur in der üblichen Art und Weise einen Fehlercode zurückzugeben. Standardmäßig ist dieses Attribut nicht aktiviert. Ist dieses Attribut gesetzt, veranlaßt jeder zu einem Fehler führende Methodenaufruf ($DBI::err ist wahr) DBI zum Aufruf von 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. Ü:.)

ChopBlanks (boolean, inherited)
Mit diesem Attribut können Sie das Entfernen führender Leerzeichen aus Char-Feldern fester Länge steuern. Andere Feldtypen sind hiervon nicht betroffen.

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.

LongReadLen (integer, inherited)
Mit diesem Attribut können Sie die maximale Länge von 'long'- (oder 'blob'-) Feldern festlegen. Der Treiber liest diesen Wert automatisch von der Datenbank ein, wenn er das Feld über eine fetch-Operation einliest. Der Wert 0 bedeutet, daß long-Daten nicht automatisch eingelesen werden. (fetch muß undef für long-Felder zurückliefern, wenn LongReadLen 0 ist.)

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.

LongTruncOk (boolean, inherited)
Dieses Attribut kann genutzt werden, um das Einlesen eines long-Feldes zu kontrollieren, das abgeschnitten wurde (üblicherweise, weil es länger war als der im LongReadLen-Attribut abgelegte Wert).

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.

private_*
DBI bietet die Möglichkeit, in einem DBI-Handle zusätzliche Informationen als 'private' Attribute abzuspeichern. DBI erlaubt es Ihnen, alle mit 'private_' beginnenden Attribute abzuspeichern und auch wieder zu lesen. Es wird eindringlich empfohlen, nur mit einem privaten Attribut (z.B. einer Hashreferenz) zu arbeiten und diesem Attribut einen Namen zu geben, der den Namen des Moduls oder der Anwendung enthält, zu dem/der das Attribut gehört (z.B. 'private_DBD_Foo_thingy').


DBI-Datenbankhandle-Objekte


Methoden für Datenbankhandles

prepare
$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.

prepare_cached
$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.

do
$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.

commit
$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.

rollback
$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.

disconnect
$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.

ping
$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.

quote
$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.


Attribute für Datenbankhandles

Dieser Abschnitt beschreibt die nur für Datenbankhandles verfügbaren Attribute.

Ä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

AutoCommit (boolean)
Ist dieses Attribut wahr, können Datenbankänderungen nicht rückgängig gemacht werden (rollback). Ist der Wert falsch, werden Datenbankänderungen innerhalb einer 'Transaktion' vorgenommen; die Änderungen müssen aber mit commit bestätigt bzw. mit rollback zurückgenommen werden.

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.


DBI-Anweisungshandle-Objekte


Methoden für Anweisungshandles

bind_param
$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.

bind_param_inout
$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.

execute
$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.

fetchrow_arrayref
$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. Ü.)

fetchrow_array
@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.

fetchrow_hashref
$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.

fetchall_arrayref
$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.

finish
$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.

rows
$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.

bind_col
$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".

bind_columns
$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.


Attribute für Anweisungshandles

Dieser Abschnitt beschreibt den Anweisungshandles eigene Attribute. Die meisten dieser Attribute können nur gelesen werden.

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. Ü.)

NUM_OF_FIELDS (integer, read-only)
Anzahl der durch die vorbereitete Anweisung zurückgegebenen Felder (Spalten). Bei Nicht-select-Anweisungen hat NUM_OF_FIELDS den Wert 0.

NUM_OF_PARAMS (integer, read-only)
Die Anzahl der Parameter (Platzhalter) in der vorbereiteten Anweisung.

NAME (array-ref, read-only)
Gibt eine Referenz auf ein Array mit den Namen aller Felder zurück. Die Namen können Leerzeichen enthalten, sollten aber nicht abgeschnitten sein und auch keine führenden Leerzeichen enthalten.

print "First column name: $sth->{NAME}->[0]\n";

NULLABLE (array-ref, read-only)
Gibt eine Referenz auf ein Array zurück, das angibt, welche Felder eine Null zurückgeben können.

print "First column may return NULL\n" if $sth->{NULLABLE}->[0];

CursorName (string, read-only)
Gibt (falls vorhanden) den Namen des Cursors zurück, der mit dem Anweisungshandle verknüpft ist. Falls dieser nicht verfügbar ist, oder falls der Datenbanktreiber die SQL-Syntax "where current of ..." nicht unterstützt, wird undef zurückgegeben.


Informationen für Fortgeschrittene


Transaktionen

Transaktionen sind ein grundlegender Bestandteil jedes robusten Datenbanksystems. Sie schützen die Datenbank vor Fehlern und Beschädigungen, indem sie sicherstellen, daß Gruppen zusammengehörender Änderungen in der Datenbank "atomar" (unsichtbar, alles oder nichts) stattfinden.

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.


Behandlung von BLOB-/Long-/Memo-Feldern

Viele Datenbanken unterstützen 'blob' (Binary Large Objects), 'long' oder ähnliche Datentypen zur Aufnahme sehr langer Strings oder großer Mengen binärer Daten in einem einzelnen Feld. Einige Datenbanken unterstützen long-Werte variabler Länge mit einer Größe von über 2 Gigabyte.

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.


Ein einfaches Beispiel

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;


Debugging

Zusätzlich zum Aufruf der trace-Methode können Sie die gleichen Tracing-Informationen auch aktivieren, indem Sie die Umgebungsvariable DBI_TRACE vor dem Start von Perl setzen.

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.


Warnungen und Fehlermeldungen

(Diesem Abschnitt fehlt es noch an Informationen zu Ursachen und möglichen Abhilfen.)


Fatale Fehler

DBI/DBD internal version mismatch (DBI is v%d/s%d, DBD %s expected v%d/s%d) you need to rebuild either the DBD driver or the DBI (Diese Meldung kann ausgegeben werden, wenn man etwa eine neue DBI-Version installiert hat, ohne auch die DBD-Module neu zu installieren. - Anm. d. Ü.)
DBD driver has not implemented the AutoCommit attribute (Es wurde versucht, $dbh->{AutoCommit} auf 0 zu setzen, obwohl die Datenbank keine Transaktionen unterstützt. - Anm. d. Ü.)
Can't [sg]et %s->{%s}: unrecognised attribute (Ein unbekanntes Attribut sollte gesetzt oder gelesen werden; typischerweise ein Schreibfehler im Attributnamen. - Anm. d. Ü.)
panic: DBI active kids (%d) > kids (%d) (Diese Meldung, ebenso wie die folgende, kann eigentlich nur bei einem Fehler im DBD-Modul auftauchen. - Anm. d. Ü.)
panic: DBI active kids (%d) < 0 or > kids (%d)


Warnungen

DBI Handle cleared whilst still holding %d cached kids!
DBI Handle cleared whilst still active!
DBI Handle has uncleared implementors data
DBI Handle has %d uncleared child handles
(Alle diese Meldungen deuten auf interne Fehler im DBD-Modul hin. - Anm. d. Ü.)


Siehe auch


Datenbankdokumentation

SQL Language Reference Manual.


Bücher und Zeitschriften

Programmieren mit Perl, von Larry Wall, Tom Christiansen & Randal Schwartz
Einführung in Perl von Randal Schwartz

Dr Dobb's Journal, November 1996
The Perl Journal, April 1997


Manual Pages

perl(1), perlmod(1), perlbook(1)


Mailing-Listen

Die Mailing-Liste dbi-users ist der primäre Kommunikationskanal für die Verwendung von DBI und verwandter Module. Aufnahme und Austritt erfolgen über:

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


Verschiedene verwandte WWW-Links

Die DBI-'Homepage' (wird nicht von mir gepflegt):

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


FAQ

Bitte lesen Sie auch die DBI-FAQ, die als DBI::FAQ-Modul installiert ist. Sie können perldoc nutzen, um sie zu lesen. Geben Sie einfach den Befehl perldoc DBI::FAQ ein.


Autoren

DBI stammt von Tim Bunce. Dieser pod-Text ist von Tim Bunce, J. Douglas Dunlop, Jonathan Leffler und anderen. Perl stammt von Larry Wall und den perl5-porters.


Übersetzer

Deutsche Übersetzung von Peter Klicman,
© 1998 by O'Reilly Verlag, Köln


Copyright

Das DBI-Modul ist Copyright (c) 1995,1996,1997 Tim Bunce. England. Alle Rechte vorbehalten.

You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.


Danksagungen

Ich möchte mich für die sehr wertvollen Beiträge der vielen Leute bedanken, mit denen ich am DBI-Projekt gearbeitet habe. Das gilt besonders für die frühen Jahre (1992-1994). Ohne besondere Reihenfolge: Kevin Stock, Buzz Moschetti, Kurt Andersen, Ted Lemon, William Hails, Garth Kennedy, Michael Peppler, Neil S. Briscoe, Jeff Urlwin, David J. Hughes, Jeff Stander, Forrest D Whitcher, Larry Wall, Jeff Fried, Roy Johnson, Paul Hudson, Georg Rehfeld, Steve Sizemore, Ron Pool, Jon Meek, Tom Christiansen, Steve Baumgarten, Randal Schwartz und noch sehr viele mehr.


Support / Garantie

DBI ist freie Software.

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.


Was noch zu tun bleibt

Datentypen (ISO-Typen und -Namen sowie ihre Beziehungen)
Fehlerbehandlung
Data-Dictionary-Methoden
Entwicklung einer Testsuite sowie unterstützende Methoden
Portabilität
blob_read
etc.


Häufig gestellte Fragen

Eine umfangreichere Liste häufig gestellter Fragen finden Sie in der (englischen) DBI-FAQ. Um sie zu lesen, verwenden Sie den Befehl perldoc DBI::FAQ.


Wie schnell ist DBI?

Um die Geschwindigkeit des DBI- und DBD::Oracle-Codes zu messen, habe ich DBD::Oracle so modifiziert, daß der gleiche Datensatz immer und immer wieder aus dem Cache gelesen wird (ohne den Oracle-Code zu nutzen, aber mit dem *gesamten* DBI- und DBD::Oracle-Code im Codepfad einer Fetch-Operation).

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.)


Warum funktioniert mein CGI-Skript nicht?

Lesen Sie die Informationen in den nachfolgenden Referenzen. Bitte senden Sie keine CGI-orientierten Fragen an die dbi-users-Mailing-Liste (oder an mich).

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.


Wie kann ich eine WWW-Verbindung zu einer Datenbank pflegen?

Informationen zum Apache-httpd-Server und dem mod_perl-Modul finden Sie unter:

http://perl.apache.org/


Die Kompilierung eines Treibers ist fehlgeschlagen, weil DBIXS.h nicht gefunden werden konnte.

Der Pfad der Datei DBIXS.h hat sich mit der Version 0.77 geändert (sie war im 'falschen' Verzeichnis abgelegt, wurde dann aber von Entwicklern an dieser Stelle erwartet). Prüfen Sie zuerst, ob Sie die neueste Version Ihres Treibers besitzen. Die Entwickler von Treibern werden neue Releases herausbringen, in der die neue Position berücksichtigt wird. Wenn Sie die neueste Version haben, fragen Sie nach einer neuen Release. Sie können die Datei Makefile.PL selbst editieren. Ändern Sie den Teil, in dem "-I.../DBI" zu finden ist, in "-I.../auto/DBI" (wobei ... ein String ohne Leerzeichen ist).


Wurden DBI und DBD::Foo auf NT / Win32 portiert?

Die neuesten Versionen von DBI und (zumindest) des DBD::Oracle-Moduls können--ohne Änderungen-- auf NT/Win32 kompiliert werden, wenn Sie die Standard-Perl-5.004-Distribution verwenden und nicht den ActiveWare-Port.

Jeffrey Urlwin (oder ) hilft mir bei der Portierung (tatsächlich macht er sie, und ich integriere die Änderungen :-).


Was ist mit ODBC?

Ein DBD::ODBC-Modul ist verfügbar.


Hat das DBI ein Jahr-2000-Problem?

Nein. Das DBI hat keinerlei Kenntnis oder Vorstellung von so etwas wie einem Datum.

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


Bekannte Treibermodule

ODBC - DBD::ODBC
Autor:  Tim Bunce
E-Mail:   dbi-users@fugue.com

Oracle - DBD::Oracle
Autor:  Tim Bunce
E-Mail:   dbi-users@fugue.com

Ingres - DBD::Ingres
Autor:  Henrik Tougaard
E-Mail:   ht@datani.dk,  dbi-users@fugue.com

mSQL - DBD::mSQL
DB2 - DBD::DB2
Empress - DBD::Empress
Informix - DBD::Informix
Autor:  Jonathan Leffler
E-Mail:   johnl@informix.com, dbi-users@fugue.com

Solid - DBD::Solid
Autor:  Thomas Wenrich
E-Mail:   wenrich@site58.ping.at, dbi-users@fugue.com

Postgres - DBD::Pg
Autor:  Edmund Mergl
E-Mail:   E.Mergl@bawue.de, dbi-users@fugue.com

Illustra - DBD::Illustra
Autor:  Peter Haworth
E-Mail:   pmh@edison.ioppublishing.com, dbi-users@fugue.com

Fulcrum SearchServer - DBD::Fulcrum
Autor:  Davide Migliavacca
E-Mail:   davide.migliavacca@inferentia.it


Verwandte Arbeiten und Perl-Module

Apache::DBI von E.Mergl@bawue.de
Zur Verwendung mit dem Apache-Daemon und einem eingebetteten Perl-Interpreter wie mod_perl gedacht. Baut eine Datenbankverbindung auf, die während der gesamten Lebensdauer des http-Daemons offenbleibt. Auf diese Weise wird der CGI-Verbindungsaufbau und -abbau für jeden Datenbankzugriff überflüssig.

JDBC-Server von Stuart 'Zen' Bishop
Der Server ist in Perl geschrieben. Die mit ihm kommunizierenden Client-Klassen sind natürlich in Java. Auf diese Weise ist ein Java-Applet oder eine Java-Anwendung in der Lage, über das JDBC-API mit allen Datenbanken zu kommunizieren, für die ein DBI-Treiber installiert ist. Die verwendete URL hat die Form jdbc:dbi://host.domain.etc:999/Driver/DBName. Scheint einigen kommerziellen Produkten wie jdbcKona sehr ähnlich zu sein.

Remote-Proxy-DBD
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. Ü.)

SQL-Parser
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. Ü.)