Perl-Programmierung: DBI

Aus Wikibooks

Wechseln zu: Navigation, Suche
Zurück zu mod_perl | Hoch zu Inhaltsverzeichnis | Vor zu CPAN


Inhaltsverzeichnis

[Bearbeiten] Einleitung

Perl besitzt dank des DBI-Moduls[1] und diversen Datenbanktreibern (engl. database drivers, DBD) eine Schnittstelle, um mit verschiedenen Datenbanksystemen arbeiten zu können. Darunter fallen populäre Open-Source-Produkte wie MySQL und PostgreSQL sowie kommerzielle Riesen wie Oracle. Derzeit umfasst dieser Abschnitt die Möglichkeiten der Anbindung an MySQL, PostgreSQL und CSV-Dateien.

[Bearbeiten] MySQL-Zugriff mit DBI

Mit Perl und dem DBI-Modul ist es verhältnismäßig leicht, sich mit einer MySQL-Datenbank zu verbinden und Abfragen abzusetzen. So fern das geeignete Perl-Modul für die Verbindung zu MySQL installiert ist ( DBD::mysql[2] ), kann es auch schon losgehen. Beim Verbindungsaufbau kann man noch allerhand Fein-Tuning betreiben, wie zB mit dem RaiseError- oder dem AutoCommit-Switch. Für weiterführende Erklärungen sollte man die Dokumentation des DBI-Moduls konsultieren. Des Weiteren benötigt man ausreichende SQL-Kenntnisse.


Im Sinne der Sicherheit, Portabilität und Faulheit ist anzumerken, dass es nur von Vorteil ist, die Zugangsdaten in einer externen Datei ( eventuell in Form eines Moduls ) einfach in jedes Script einzubinden, damit, falls sich die Zugangsdaten ändern sollten, der Verwaltungsaufwand gering gehalten wird. Ansonsten müssten die Daten in jedem Script händisch angepasst werden. Außerdem ist in diesem Fall auch die Weitergabe des Quelltextes eher unbedenklich, da die brisante Information in einer separaten Datei steckt. Dieses externe File sollte dann verständlicherweise nicht für jedermann lesbar sein. In folgendem Code-Beispiel wurde jedoch aus Gründen der Einfachheit darauf verzichtet.


[Bearbeiten] Einfaches Beispiel

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use DBI;
  5.  
  6. # Deklaration der noetigen Variablen fuer die Verbindung
  7. # Falls die Datenbank nicht lokal liegt, muss man zusaetzlich
  8. # die Variablen $dbhost und/oder $dbport angeben
  9. # my $db_host = "127.0.0.1";
  10. # my $db_port = "3306";
  11.  
  12. my ($db_user, $db_name, $db_pass) = ("deinuser", "deineDB", "deinpass");
  13.  
  14. # Verbindung zur DB herstellen
  15. # alternativ ( wenn DB nicht lokal ):
  16. # my $dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host;port=$db_port",
  17. #                         "$db_user", "$db_pass");
  18.  
  19. my $dbh = DBI->connect("DBI:mysql:database=$db_name", "$db_user", "$db_pass");
  20.  
  21. # Vorbereiten des SQL-Statements
  22.  
  23. my $query_test = $dbh->prepare("SELECT * FROM deinetabelle");
  24.  
  25. # Ausfuehren des Statements
  26.  
  27. $query_test->execute() or die $query_test->err_str;
  28.  
  29. # Hier koennte weitergehende Verarbeitung erfolgen, eine Auflistung aller Eintraege zB:
  30.  
  31. while (my ($col_1, $col_2, $col_3) = $query_test->fetchrow_array) {
  32.     print "Spalte 1: " . $col_1 . "\n";
  33.     print "Spalte 2: " . $col_2 . "\n";
  34.     print "Spalte 3: " . $col_3 . "\n";
  35. }
  36.  
  37. # Nun erstellen wir doch noch gleich eine neue Tabelle
  38. # Statt der Möglichkeit mittels vorherigem prepare und execute, benutzen
  39. # wir hier die einfache Methode do
  40.  
  41. my $create_query = "CREATE table testtable";
  42.  
  43. $dbh->do($create_query);
  44.  
  45. # Nachdem alles erledigt ist, schließen wir die Datenbankverbindung
  46.  
  47. $dbh->disconnect;


Die eigentliche Arbeit in diesem Script steckt in Zeile 31. Hier wird mittels der Funktion fetchrow_array jeweils eine Zeile in eine Liste/Array eingelesen und zurückgeliefert. Die ersten 3 Werte dieser Liste werden danach den Werten $col_1 bis $col_3 zugewiesen. Sobald fetchrow_array keine Zeile mehr zurückliefert, beendet sich die while-Schleife.

[Bearbeiten] Erweitertes Beispiel mit Modulanbindung

Hier eine von vielen Möglichkeiten die Verbindungsdaten in einem externen File unterzubringen. Der folgende Ansatz bindet die Daten mittels eines Moduls ein.


Das externe File mit den Daten ( ExterneDaten.pm ):

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. our @EXPORT_OK = qw($DB_USER $DB_PASSWD $DATABASE);
  5. use Exporter;
  6. our @ISA = qw(Exporter);
  7.  
  8. package ExterneDaten;
  9. our $DB_USER   = "youruser";
  10. our $DB_PASSWD = "yourpasswd";
  11. our $DATABASE  = "yourDB";
  12.  
  13. 1;


Dieses File sollte nun mit entsprehend sicheren Zugriffsrechten versehen werden und den Namen ExterneDaten.pm erhalten. Nachdem das erledigt ist, kann man das erste Beispiel auch wie folgt formulieren:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use DBI;
  5. use lib ".";
  6. use ExterneDaten;
  7.  
  8. # Verbindung zur DB herstellen
  9.  
  10. my $dbh = DBI->connect("DBI:mysql:database=$ExterneDaten::DATABASE",
  11.                         "$ExterneDaten::DB_USER", "$ExterneDaten::DB_PASSWD");
  12.  
  13. # Vorbereiten des SQL-Statements
  14.  
  15. my $query_test = $dbh->prepare("SELECT * FROM deinetabelle");
  16.  
  17. # ...
  18. # ... alles andere bleibt gleich
  19. # ...


Erklärung

In Zeile 5 wird Perl angewiesen das aktuelle Verzeichnis in das @INC-Array aufzunehmen, dies ist notwendig, damit ExterneDaten.pm danach auch, wie in Zeile 6 gefordert, gefunden wird. Durch die package-Anweisung im Modul befinden sich die Variablen im ExterneDaten-Namensraum, weshalb den eigentlichen Variablennamen ExterneDaten:: vorangestellt wird.

[Bearbeiten] DBI-Zugriff auf andere Datenbanksysteme

Im wesentlichen können hier die Erkenntnisse des letzten Kapitels übernommen werden. Den größten Unterschied stellt lediglich die connect-Anweisung dar, die für jedes DBMS etwas anders ausschaut. Des weiteren sollten, um die folgenden Beispiele ausführen zu können, die Module DBD::Pg[3] für PostgreSQL sowie DBD::CSV[4] für CSV installiert sein. Beide Module sind im CPAN zu finden.

[Bearbeiten] PostgreSQL

my $dbh = DBI->connect("DBI:Pg:dbname=$db_name", "$db_user", "$db_pass");

[Bearbeiten] Ein CSV-Verzeichnis

CSV steht für "Comma-separated Values", und bezeichnet keine Datenbank im eigentlichen Sinne, sondern einen Dateityp, eigentlich reine Textdateien im ASCII-Format, die von jedem Texteditor gelesen und bearbeitet werden können. Damit hat der Programmierer die Möglichkeit, SQL zu nutzen, ohne ein DBMS installieren zu müssen. Vorteilhaft, wenn man sparsam mit den Ressourcen umgehen muß.

Als Datenbank verwendet man ein Verzeichnis, und jede CSV-Datei steht für eine Tabelle. Benutzername und Passwort entfallen.

my $dbh = DBI->connect("DBI:CSV:f_dir=/pfad/zu/deinem/csvverzeichnis");
 
#Oder bei Windows
my $dbh = DBI->connect("DBI:CSV:f_dir=c:\\pfad\\zu\\deinem\\csvverzeichnis");

[Bearbeiten] SDBM

SDBM (Standard-Perl-Quelldistribution) ist eine sehr einfache Datenbank, die häufig bei einer gewöhnlichen Linux-Distribution standardmäßig installiert wird. Es werden zwei Dateien erzeugt. Eine mit der Endung .dir und eine .pag, wobei letztere die Daten beinhaltet.

Hier ein erklärendes Beispiel eingebettet in eine Klasse:

package cl_db;
 
use Fcntl;                                    # O_RDWR, O_CREAT, etc.
use SDBM_File;
 
sub new                                       # Konstruktor
{
    my $this  = shift;
    my $class = ref($this) || $this;
 
    my $self  = {
        temperatur => {},                     # Temperaturwerte
    };
 
    bless $self, $class;                      # Objekt erzeugen
 
    tie(%{$self->{temperatur}}, 'SDBM_File',"temperatur.db", O_RDWR|O_CREAT, 0666);
 
    return $self;
}

Der Konstruktor verbindet das Hash %self{temperatur} mit der Datenbank (temperatur.db). Es werden im aktuellen Verzeichnis die beiden Dateien temperatur.db.dir und temperatur.dp.pag angelegt bzw. benutzt.

sub writeDB
{
    my $self = shift;
    my $key  = shift;                         # Datenschluessel
    my $data = shift;                         # Datenwert
 
    $self->{temperatur}->{$key} = $data;
 
    return 1;
}

Die Funktion writeDB schreibt Daten in die Datenbank.

sub readDB
{
    my $self = shift;
    my $key  = shift;                         # Datenschluessel
 
    return $self->{temperatur}->{$key};
}

Die Funktion readDB liest bestimmte Daten der Datenbank aus.

sub DESTROY
{
    my $self = shift;
 
    untie %{$self->{temperatur}};
}
1;                                            # Returnwert für Package

Der Destruktor löst die Verbindung wieder auf und schließt somit die Datenbank wieder.


Das folgende Beispiel zeigt, wie diese Klasse benutzt werden kann:

#!/usr/bin/perl -w
 
use cl_db;
 
my $db = cl_db->new();                        # Konstruktor wird aufgerufen
$db->writeDB("InnenTemperatur", 21.0);        # Daten schreiben
print "Innentemperatur: ", $db->readDB("InnenTemperatur"), "\n"; # Daten lesen

[Bearbeiten] Module

  1. CPAN: DBI
  2. CPAN: DBD::mysql
  3. CPAN: DBD::Pg
  4. CPAN: DBD::CSV


Zurück zu mod_perl | Hoch zu Inhaltsverzeichnis | Vor zu CPAN


Persönliche Werkzeuge
Buch erstellen