42

Click here to load reader

Perl/DBI - accessing databases from Perl

  • Upload
    barton

  • View
    107

  • Download
    7

Embed Size (px)

DESCRIPTION

Perl/DBI - accessing databases from Perl. Dr. Andrew C.R. Martin [email protected] http://www.bioinf.org.uk/. Aims and objectives. Understand the need to access databases from Perl Know why DBI? Understand the structure of DBI - PowerPoint PPT Presentation

Citation preview

Page 1: Perl/DBI - accessing databases from Perl

Perl/DBI - accessing databases from Perl

Dr. Andrew C.R. [email protected]://www.bioinf.org.uk/

Page 2: Perl/DBI - accessing databases from Perl

Aims and objectivesUnderstand the need to access

databases from PerlKnow why DBI?Understand the structure of DBIBe able to write a Perl/DBI script

to read from or write to a databasePRACTICAL: write a script to read

from a database

Page 3: Perl/DBI - accessing databases from Perl

Why access a database from Perl?

Page 4: Perl/DBI - accessing databases from Perl

CGIScript

Why access a database from Perl?

Send request for page to web server

Pages

ExternalPrograms

RDBMS

Web browserWeb server

CGI can extract parameters sent with the page request

Page 5: Perl/DBI - accessing databases from Perl

Why access a database from Perl?

Populating databasesNeed to pre-process and re-format

data into SQLIntermediate storage during data

processing

Reading databasesGood database design can lead to

complex queries (wrappers)Need to extract data to process it

Page 6: Perl/DBI - accessing databases from Perl

Why use DBI?

Page 7: Perl/DBI - accessing databases from Perl

Why Perl/DBI?

Many relational databases available.Commercial examples:

OracleDB/2SQLServerSybaseInformixInterbase

Open source examples:PostgreSQLmySQL

Page 8: Perl/DBI - accessing databases from Perl

Why Perl/DBI?Databases use a common query

language: ‘structured query language’ (SQL)

Queries can easily be ported between different database softwareMinor variations in more advanced

features

Proprietary extensions

Page 9: Perl/DBI - accessing databases from Perl

Why Perl/DBI?Can call command-line interface

from within your program.

$result = `psql -tqc “SELECT * FROM table” `;

@tuples = split(/\n/, $result);foreach $tuple (@tuples){ @fields = split(/\|/, $tuple);}

Inefficient: new process for each database access

Page 10: Perl/DBI - accessing databases from Perl

Why Perl/DBI?Databases generally provide own

APIs to allow access from programming languagese.g. C, Java, Perl

Proprietary APIs all differ

Very difficult to port software between databases

Standardized APIs have thus become available

Page 11: Perl/DBI - accessing databases from Perl

Why Perl/DBI?Perl/DBI is the standardized API for

Perl

Easy to port Perl scripts from one database to another

Page 12: Perl/DBI - accessing databases from Perl

DBI and ODBCODBC (Open DataBase Connectivity)Consortium of vendors in early 1990s

SQL Access GroupOctober 1992 & 1993, draft

standard:‘Call Level Interface’ (‘CLI’ - an API)Never really adopted

Microsoft ‘embraced and extended’ it to create ODBC

Page 13: Perl/DBI - accessing databases from Perl

DBI and ODBC‘DBPerl’ designed as database

interface specifically for Perl4September 1992 (i.e. pre-ODBC)

Just before release, Perl5 announced with OO facilities

DBPerl modified to support OO and loosely modelled on CLI standard

This became DBI

Page 14: Perl/DBI - accessing databases from Perl

DBI and ODBC

Standard SQL syntax Dodged this issue!

Standard error codes Check $DBI::err or $DBI::errstr (DBI provides methods for standard errors, but drivers don’t use them)

Meta-data on database structure

Tables and types only

Many attributes and options to tweak underlying driver

Very limited control

ODBC DBI

Page 15: Perl/DBI - accessing databases from Perl

DBI and ODBCThere is an ODBC driver for DBI DBI can be used to access any

ODBC database

Page 16: Perl/DBI - accessing databases from Perl

The structure of DBI

Page 17: Perl/DBI - accessing databases from Perl

DBI Architecture

Oracledriver

mySQLdriver

PostgreSQLdriver

Sybasedriver

DBI

Page 18: Perl/DBI - accessing databases from Perl

DBI ArchitectureMulti-layer design

Perl script

DBI

DBD

Database API

RDBMS

DatabaseIndependent

DatabaseDependent

Page 19: Perl/DBI - accessing databases from Perl

DBD::Oracle

DBD::Oracle

DBD::Oracle

PerlScript

PerlScript

DBI Architecture

PerlScript DBI DBD::mysql

DBD::Oracle

DBD::Pg

Oracle

mySQL

PostgreSQL

Page 20: Perl/DBI - accessing databases from Perl

DBI Architecture

Returns a list of installed (DBD) drivers

@drivers = DBI->available_drivers();

Page 21: Perl/DBI - accessing databases from Perl

DBI Architecture

DBD::OracleDriver Handle

DBD::pgDriver Handle

DatabaseHandle

DatabaseHandle

DatabaseHandle

StatementHandle

StatementHandle

StatementHandle

StatementHandle

StatementHandle

StatementHandle

StatementHandle

Page 22: Perl/DBI - accessing databases from Perl

DBI Architecture

Driver Handles

References loaded driver(s)One per driver

Not normally referenced in programs

Standard variable name $drh

Page 23: Perl/DBI - accessing databases from Perl

DBI ArchitectureDatabase HandlesCreated by connecting to a database

References a database via a driverCan have many per database (e.g.

accessing different user accounts)Can access multiple databasesStandard variable name $dbh

$dbh = DBI->connect($datasource, ... );

Page 24: Perl/DBI - accessing databases from Perl

DBI Architecture

Statement HandlesCreated by ‘preparing’ some SQL

Can have many per database handle (e.g. multiple queries)

Standard variable name $sth

$sth = $dbh->prepare($sql);

Page 25: Perl/DBI - accessing databases from Perl

DBI Architecture

DBD::pgDriver Handle

DatabaseHandle

StatementHandle

$dbh = DBI->connect($datasource, ... );

$sth = $dbh->prepare($sql);

Page 26: Perl/DBI - accessing databases from Perl

SQL Preparation

prepare()

Perl script DBI and Driver Database

Pass statementto database engine

$sth

Encapsulate as DBI

statement handle

ParseStatement

EncapsulateStatement

if valid

Pass statementto database engine

execute()

fetchrow_array()

Maintain cursorinto results

ExecuteStatement

Page 27: Perl/DBI - accessing databases from Perl

Writing Perl/DBI scripts

Page 28: Perl/DBI - accessing databases from Perl

Accessing DBI from PerlMust have the DBI package and

appropriate DBD package installedDBD::Oracle, DBD::Pg, DBD::mysql, etc.

use DBI;

$dbh = DBI->connect($datasource, $username, $password);

Create a ‘handle’ to access the database:

The DBD moduleand d/b to be used

Page 29: Perl/DBI - accessing databases from Perl

Data sources

$dbname = “mydatabase”;

$dbserver = “dbserver.cryst.bbk.ac.uk”;$dbport = 5432;

$datasource = “dbi:Oracle:$dbname”;$datasource = “dbi:mysql:database=$dbname;host=$dbserver”;$datasource = “dbi:Pg:dbname=$dbname;host=$dbserver;port=$dbport”;

Format varies withdatabase module

$dbh = DBI->connect($datasource, $username, $password);

Optional; supported by some databases.

Default: local machine and default port.

Page 30: Perl/DBI - accessing databases from Perl

Username and password

$username and $password also optionalOnly needed if you normally need a

username/password to connect to the database.

Remember CGI scripts run as a special web-server user. Generally, ‘nobody’ or ‘apache’.

Database must allow access by this useror specify a different username/password

$dbh = DBI->connect($datasource, $username, $password);

Page 31: Perl/DBI - accessing databases from Perl

SQL commands with no return valueSQL commands other that SELECT don’t

return values may return success/failure flagnumber of entries in the database affected

For example: creating a table inserting a row modifying a row

Page 32: Perl/DBI - accessing databases from Perl

SQL commands with no return value

From Perl/DBI:

INSERT INTO idac VALUES (‘LYC_CHICK’, ‘P00698’)

e.g. insert a row into a table:

$sql = “INSERT INTO idac VALUES (‘LYC_CHICK’, ‘P00698’)”;$dbh->do($sql);

Page 33: Perl/DBI - accessing databases from Perl

SQL commands that return a single rowSometimes, can guarantee that a

database query will return only one rowor you are only interested in the first row

$sql = “SELECT * FROM idac WHERE ac = ‘P00698’”;@values = $dbh->selectrow_array($sql);

Columns placed in an array

Could also have been placed in a list:

($id, $ac) = $dbh->selectrow_array($sql);

Page 34: Perl/DBI - accessing databases from Perl

SQL commands that return a multiple rows

Most SELECT statements will return many rows

Three stages must be performed:

preparing the SQL

executing it

extracting the results

Page 35: Perl/DBI - accessing databases from Perl

SQL commands that return a multiple rows

(Can also obtain array or hash reference) NB: statement handle / fetchrow_array rather than db handle / selectrow_array

$sql = “SELECT * FROM idac”;

$sth = $dbh->prepare($sql);if($sth->execute){ while(($id, $ac) = $sth->fetchrow_array) { print “ID: $id AC: $ac\n”; }}

Page 36: Perl/DBI - accessing databases from Perl

SQL commands that return a multiple rows If you need to stop early you can do:

$sql = “SELECT * FROM idac”;

$sth = $dbh->prepare($sql);if($sth->execute){ for($i=0; $i<10; $i++) { if(($id, $ac) = $sth->fetchrow_array) { print “ID: $id AC: $ac\n”; } } $sth->finish;}

Page 37: Perl/DBI - accessing databases from Perl

SQL commands that return a multiple rowsA utility method is also available to print

a complete result set:

$sql = “SELECT * FROM idac”;$sth = $dbh->prepare($sql);if($sth->execute){ $nrows = $sth->dump_results;}

(Mostly useful for debugging)

Page 38: Perl/DBI - accessing databases from Perl

Repeated SQL callsOften want to repeat essentially the

same query, but with some different value being checked.

For example:

foreach $ac (‘P00698’, ‘P00703’){ $sql = “SELECT * FROM idac WHERE ac = ‘$ac’”; @values = $dbh->selectrow_array($sql); print “@values\n”;}

(using special option for 1-row returns)

Page 39: Perl/DBI - accessing databases from Perl

Repeated SQL callsCould also be do:

foreach $ac (‘P00698’, ‘P00703’){ $sql = “SELECT * FROM idac WHERE ac = ‘$ac’”; $sth = $dbh->prepare($sql); $sth->execute; while(@values = $sth->fetchrow_array) { print “@values\n”; }}

i.e. don’t use special option for 1-row returns $dbh->selectrow_array($sql)

Page 40: Perl/DBI - accessing databases from Perl

Repeated SQL calls Increase in performance by ‘binding’ a

variable:$sql = “SELECT * FROM idac WHERE ac = ?”;$sth = $dbh->prepare($sql);

foreach $ac (‘P00698’, ‘P00703’){ $sth->bind_param(1, $ac); $sth->execute; while(@values = $sth->fetchrow_array) { print “@values\n”; }}

Parameter Number

Variableto bind

Page 41: Perl/DBI - accessing databases from Perl

Repeated SQL callsNOTE:Performance increase depends on

database and driverAlthough strings normally enclosed in

single inverted commas, the bound variable is not quoted.

If you have a number which you need to be treated as a string, then you do:

$sth->bind_param(1, 42, SQL_VARCHAR);

Page 42: Perl/DBI - accessing databases from Perl

SummaryDBI provides a standard API It does not standardize the SQLDBI is an older standard than ODBC

They can be used together and they are both evolving

Basic 3-step process:prepare / execute / fetch

Shortcut calls for no return or 1-row return

Many other functions available