DBI/DBDモジュール について調べてみた

概要

DBI/DBDは、データベースにアクセスするための手段と、データベースの種類に依存しないインターフェイスを提供します。

DBI(データベース・インタフェイス)モジュールとDBD(データベース・ドライバ)モジュールからできており、DBDモジュールは各データベースごとに存在します。プログラマは、DBIモジュールのルールにしたがってプログラミングすることで、どのデータベースにも同じ方法で操作することができます。

目次

  1. モジュール読み込み
  2. DBへ接続
  3. ステートメントの準備
  4. ステートメントの実行
  5. (データの取り出し)
  6. DBを切断

モジュール読み込み [DBIモジュール]

データベースに接続するには、最初にDBIモジュールを読み込みます。

 # DBI モジュールの読み込み
 use DBI;

DBへ接続 [データベースハンドル](DBIモジュール::connect)

次にDBIモジュールのconnectメソッドを使ってデータベースに接続します。

connectメソッドは、[データソース]、[ユーザ名]、[パスワード]の引数を受け取り、データベースハンドルオブジェクトへのリファレンスを返します。
データソースは、[DBI]:[DBMS名]:[データベース名]:[ホスト名]:[ポート名]で指定します。(ホスト名とポート番号は省略可。)

 # データソース
 $dsn ='DBI:mysql:dbname:www:3306';
 # ユーザ名
 $user = 'dbuser';
 # パスワード
 $password = 'dbpass';
 
 # データベースへ接続
 $dbh = DBI->connect($dsn, $user, $password);
AutoCommit(データベースハンドルプロパティ)
boolean(真/偽)型のプロパティ。
データベースハンドルについて現在のAutoCommitの状況を表しています。デフォルトは1(真)。
トランザクションを制御する場合は0(偽)を設定します。
RaiseError(共通プロパティ)
boolean(真/偽)型、継承されるプロパティ。
トランザクションと直接には関係しません。
RaiseErrorをオンにしておくことで、DBIはエラーがおこったとき、 die("$class $method failed: $DBI::errstr") と同様の処理を行います。
 # オプション指定
 $dbh = DBI->connect($dsn, $user, $password,{ RaiseError => 1, AutoCommit => 0 });

ステートメントの準備 [ステートメントハンドル](データベースハンドル::prepare)

データベースハンドルのprepareメソッドでステートメント(SQL文)を実行できるように準備(prepare)します。

prepareメソッドは、ステートメントハンドルオブジェクトへのリファレンスを返します。ステートメントハンドルはステートメントの属性を取得したり、executeメソッドを起動するために使用できます。prepareを使うとexecuteの実行速度が向上します(ただし、MySQLでは単にSQL文を保存するだけです)。

prepareだけでは何も起こりません。準備されたステートメントを実行(execute)することでSQLが実行されます。このとき、SQLの最後にセミコロンをつける必要はありません。

 # $statement 実行したいSQL文
 # $dbh connect済みのデータベースハンドル
 # \%attr メソッドに渡される属性値のハッシュのリファレンス
 
 $sth = $dbh->prepare($statement) || die $dbh->errstr;
 $sth = $dbh->prepare($statement, \%attr) || die $dbh->errstr;

このメソッドはプレースホルダが使えます。

ステートメントの実行 (ステートメントハンドル::execute)

準備(prepare)されたステートメントハンドルに対して、実行(execute)することでそのSQLが実行されます。

executeメソッドは、正常に実行された場合、trueを返し、エラーの場合はundefを返します。

SELECT文
問い合わせ結果を返します。(データを取り出す準備ができただけです。)
結果は、fetch系のメソッドで取り出すことができます。
SELECT文以外(INSERT、UPDATE、DELETE等)
処理の対象となったレコードの数、レコード数が0の場合は0E0、レコード数が不明の場合は-1を返します。
 # $sth prepareされたステートメントハンドル

 $rv = $sth->execute || die $sth->errstr;

prepareでプレースホルダを使用した場合、executeに引数@bind_valuesを指定するとそのステートメントを実行する前にbind_paramが呼び出されます。このようにして結び付けられた値は、SQL_VARCHARタイプとして扱われます(文字列のクォート等の必要はありません)。

 # $sth prepareされたステートメントハンドル
 # @bind_values バインド値
 $statement = insert into table (id, name, age) values (?, ?, ?);
 $sth = $dbh->prepare($statement);
 $rv = $sth->execute(@bind_values) || die $sth->errstr;

データの取り出し(ステートメントハンドル::fetch)

executeされたステートメントハンドル(select文)に対して、fetchメソッドを発行することで、1レコードずつデータを取り出すことができます。

fetchメソッドは、データの次の行を取り出し、フィールドの値をもった配列へのリファレンスを返します。
NULL値はundefで返されます。
$sth->bind_columnsを使っていれば、これがデータを取り出すもっとも早い方法です。

取り出せる列がないか、エラーが発生すると、undefを返します(後で$sth->errをチェックするか、RaiseErrorを使ってください)。

 # $sth prepareされたステートメントハンドル
 $sth->execute;
 while( my $ref = $sth->fetch ){
   print $ref,"\n";
 }

DBを切断(データベースハンドル::disconnect)

データベースとの接続を破棄します。通常、プログラムの終了時に実行されます。

 # $dbh connect済みのデータベースハンドル
 $rc = $dbh->disconnect;

投稿日:

ページのトップへ戻る