Perl und Oracle

01.
August
2012
Veröffentlicht von: Helmut Exner

Sie wollen SQL-Statements in Perl verwenden und an das Datenbanksystem ORACLE senden und die Ergebnisse verarbeiten? Dazu kann das Modul DBI (Database Interface) verwendet werden. Was ist DBI? DBI ist das Standard-Datenbank-Interface-Modul für Perl. Es dient als Vermittler zwischen dem Programm und einer Reihe datenbankspezifischer Treiber (DBD), die dann mit der eigentlichen Datenbank kommunizieren.

Sie wollen SQL-Statements in Perl verwenden und an das Datenbanksystem ORACLE senden und die Ergebnisse verarbeiten? Dazu kann das Modul DBI (Database Interface) verwendet werden.

Was ist DBI?

DBI ist das Standard-Datenbank-Interface-Modul für Perl. Es dient als Vermittler zwischen dem Programm und einer Reihe datenbankspezifischer Treiber (DBD), die dann mit der eigentlichen Datenbank kommunizieren.


Wie kann nun Perl und DBI in einer LINUX Umgebung benutzt werden?

Normalerweise ist Perl schon installiert:

/home/oracle:~> type perl
perl is /usr/bin/perl


Aber das Modul DBI eben nicht:

/home/oracle:~> perl -e "use DBI;"

Can't locate DBI.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl
/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl
/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.


Man musste sich nun das Modul DBI/DBD downloaden und installieren:

Opens external link in new windowhttp://www.perl.com/CPAN/modules/by-module/DBI
Opens external link in new windowhttp://www.perl.com/CPAN/modules/by-module/DBD (=der dazugehörige Oracle Treiber)

Aber das ist alles nicht mehr nötig. Perl und DBI/DBD werden mit jeder Oracle 10g/11g Software-Installation mitgeliefert.


Wohin installiert Oracle nun PERL und DBI?

Es wird im Verzeichnis $ORACLE_HOME/perl installiert (eventuell unterschiedlich mit anderen Versionen).

Das Modul DBI findet man unter:

/home/oracle:~> find $ORACLE_HOME/perl/* -name DBI.pm
/u01/app/oracle/product/11.2.0/dbhome_1/perl/lib/site_perl/5.10.0/x86_64-linux-thread-multi/DBI.pm


Jetzt muss nur noch die Pfadangabe angepasst werden und schon kann Perl und DBI verwendet werden.

/home/oracle:~> export PATH=/u01/app/oracle/product/11.2.0/dbhome_1/perl/bin:$PATH

/home/oracle:~> perl -v
This is perl, v5.10.0 built for x86_64-linux-thread-multi

/home/oracle:~> perl -MDBI -le 'print DBI->VERSION();'
1.602

/home/oracle:~> perl -MDBD::Oracle -le 'print $DBD::Oracle::VERSION;'
1.20


Auf was muss geachtet werden, wenn man DBI in Perl-Skripten verwenden möchte?

In einer Linux Umgebung muss unbedingt auf die erste Zeile geachtet werden. Diese Zeile sagt Linux, mit welchem Programm es das Skript ausführen soll. Die Pfadangabe in dieser Zeile muss dem korrekten Pfad zum Perl-Interpreter entsprechen.

Skript: DBI_demo_01.pl (In Perl-Skripten sieht man aber oft Folgendes in der ersten Zeile):

#!/usr/bin/perl

my $perl_version=`perl -v | awk '/This is perl/ {print $4}' | sed -e 's/v//'`;
print "Perl Version = $perl_version\n";

use DBI;
print "DBI version $DBI::VERSION\n" ;
print "DBD:Oracle Version $DBD::Oracle::VERSION\n" ;


Ausführen des Skripts:

/home/oracle:~> export PATH=/u01/app/oracle/product/11.2.0/dbhome_1/perl/bin:$PATH
/home/oracle:~> chmod u+x DBI_demo_01.pl
/home/oracle:~> ./DBI_demo_01.pl

Can't locate DBI.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl
/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl
/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./test1.pl line 5.
BEGIN failed--compilation aborted at ./test1.pl line 5.

Fehler - das Modul DBI wurde nicht gefunden, obwohl die Pfadangabe richtig gesetzt wurde.

Wenn aber der Interpreter Perl mit angegeben wird, sieht es schon wesentlich besser aus: 

/home/oracle:~> perl DBI_demo_01.pl

Perl Version = This is perl, 5.10.0 built for x86_64-linux-thread-multi
DBI version 1.602
DBD:Oracle Version 1.20

Die erste Zeile im Skript wird dadurch normalerweise überflüssig.


Ein Beispiel wie man es eigentlich machen sollte, so funktioniert es immer, ob der Interpreter Perl angegeben wird oder nicht

Skript: DBI_demo_02.pl

#!/usr/bin/env perl

my $perl_version=`perl -v | awk '/This is perl/ {print $4}' | sed -e 's/v//'`;
print "Perl Version = $perl_version";

use DBI;
use DBD::Oracle;

print "DBI version $DBI::VERSION\n" ;
print "DBD:Oracle Version $DBD::Oracle::VERSION\n" ;


Ausführen des Skripts :

/home/oracle:~> export PATH=/u01/app/oracle/product/11.2.0/dbhome_1/perl/bin:$PATH
/home/oracle:~> chmod u+x DBI_demo_02.pl
/home/oracle:~> ./DBI_demo_02.pl

oder

home/oracle:~> perl DBI_demo_02.pl


Ausgabe:

Perl Version = This is perl, 5.10.0 built for x86_64-linux-thread-multi
DBI version 1.602
DBD:Oracle Version 1.20


Wie schaut dies alles nun in einer Windows Umgebung aus ?

In einer Windows Umgebung ist Perl meistens ja nicht vorinstalliert.

Oracle installiert Perl und DBI wie unter Linux auch nach: %ORACLE_HOME%/perl.

Das Modul DBI findet man nun unter: %ORACLE_HOME%/perl/site/lib

Ist Perl installiert und welche Version ?

C:\Users> perl -v

Der Befehl "perl" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

Es muss nun wie unter Linux lediglich die Pfadangabe angepasst werden:

C:\Users> set PATH=c:\oracle\product\11.2.0\dbhome_1\perl\bin;%PATH%

C:\Users> perl -v
This is perl, v5.10.0 built for MSWin32-x64-multi-thread

C:\Users> perl -MDBI -le "print DBI->VERSION();"
1.602

C:\Users> perl -MDBD::Oracle -le "print $DBD::Oracle::VERSION;"
1.20


Wie ist es nun, wenn DBI in Perl-Skripten verwendet wird ?

In einer Windows Umgebung ist die Zeile #!/usr/bin/env normalerweise überhaupt nicht nötig. Sie stört aber auch nicht. Durch das # am Anfang wird sie von Perl als Kommentar betrachtet und deshalb auf anderen Plattformen als Unix einfach ignoriert.

Skript : DBI_demo_03.pl

#!/usr/bin/env perl

my $perl_version=`perl -v | findstr -i /c:"this is perl"`;
print "Perl Version = $perl_version\n";

use DBI;
use DBD::Oracle;

print "DBI version $DBI::VERSION\n" ;
print "DBD:Oracle Version $DBD::Oracle::VERSION\n" ;


Ausführen des Skripts:

C:\Users> set PATH=c:\oracle\product\11.2.0\dbhome_1\perl\bin;%PATH%
C:\Users> perl DBI_demo_03.pl

Perl Version = This is perl, v5.10.0 built for MSWin32-x64-multi-thread
DBI version 1.602
DBD:Oracle Version 1.20


Beispiel mit Verarbeitung von SQL-Statements

Skript : DBI_demo_04.pl

#!/usr/bin/env perl

use DBI;
use DBD::Oracle;

@zeile;
$oracle_user="scott";
$oracle_password="tiger";
$oracle_sid="ORCL";

### Anmelden an Datenbank

$dbh = DBI->connect("DBI:Oracle:$oracle_sid",$oracle_user,$oracle_password,
{AutoCommit => 0, RaiseError => 1 });
if($dbh){
print "\n";
print("Angemeldet als Benutzer $oracle_user\n");
}

### Anlegen Tabelle

$create = "CREATE TABLE dbi_demo(empno number(4) not null,ename VARCHAR2(10),sal number(7,2))";
$dbh->do($create);
$dbh->commit;

#### Daten einfügen in Tabelle

$insert = "Insert into dbi_demo (empno,ename,sal) values (100,'ADAMS',5000)";
$dbh->do($insert);
$insert = "Insert into dbi_demo (empno,ename,sal) values (200,'MILLER',6000)";
$dbh->do($insert);
$insert = "Insert into dbi_demo (empno,ename,sal) values (300,'JAMES',7000)";
$dbh->do($insert);

$dbh->commit;

### Anzeigen der Daten

$sth = $dbh->prepare("SELECT empno,ename,sal FROM dbi_demo");
$sth->execute();

while ((@zeile) = $sth->fetchrow_array) {
print "\n";
map {print join(", ",@zeile), "\n" } $zeile;
}

$sth->finish();

### Löschen Tabelle

$drop = "DROP TABLE dbi_demo";
$dbh->do($drop);

### Abmelden von Datenbank

if($dbh->disconnect){
print "\n";
print("Abgemeldet\n");
}


Ausführen des Skripts :

C:\Users> set PATH=c:\oracle\product\11.2.0\dbhome_1\perl\bin;%PATH%
C:\Users> perl DBI_demo_03.pl

Angemeldet als Benutzer scott

100, ADAMS, 5000
200, MILLER, 6000
300, JAMES, 7000
400, DAVID, 8000

Abgemeldet


Anmelden mit Operating System Authentication

Voraussetzungen:

Der Benutzer muss der Gruppe "DBA" unter Linux und der Gruppe "ORA_DBA" unter Windows angehören.

Ausserdem muss unter Windows in der SQLNET.ORA definiert sein:

SQLNET.AUTHENTICATION_SERVICES= (NTS)


Skript : DBI_demo_05.pl

#!/usr/bin/env perl

use DBI;
use DBD::Oracle;

### Anmelden an Datenbank als sysdba (ora_session_mode => 2)
### Anmelden an Datenbank als sysoper (ora_session_mode => 4)

$dbh = DBI->connect("DBI:Oracle:", "/", undef, {ora_session_mode => 2});

$sth=$dbh->prepare("SELECT user FROM dual");
$sth->execute;
@row=$sth->fetchrow_array;

print "\n";
printf "Angemeldet als Benutzer %s\n", $row[0];


Ausführen des Skripts :

C:\Users> set PATH=c:\oracle\product\11.2.0\dbhome_1\perl\bin;%PATH%
C:\Users> perl DBI_demo_05.pl

Angemeldet als Benutzer SYS


Zusammenfassung

Wie man sieht lassen sich mit Perl und DBI relativ einfach SQL-Statements gegen die Oracle Datenbank ausführen.
Wichtig dabei ist, dass die Umgebung (Pfadangabe) vorher richtig gesetzt wurde.
Natürlich muss auch ORACLE_HOME und ORACLE_SID richtig gesetzt sein (wurde in dem Beitrag nicht extra aufgeführt).

Jede Menge Know-how für Sie!

In unserer Know-How Datenbank finden Sie mehr als 300 ausführliche Beiträge zu den Oracle-Themen wie DBA, SQL, PL/SQL, APEX und vielem mehr.
Hier erhalten Sie Antworten auf Ihre Fragen.