「準備済みSQL命令でデータベースアクセスを効率化する」でも紹介したとおり、準備済みSQL命令は、パラメータだけが異なる同一のSQL命令を繰り返し実行する場合には有効な手法です。しかし、準備済みSQL命令でも、1回目の実行に関しては通常のSQL命令と同様に「解析→コンパイル→実行」というステップを踏む必要があります。そのため、同一命令の繰り返しが行われないデータベースアクセスの場合は、必ずしも十分な効果をあげることができません。
そこで登場するのが、ストアドプロシージャです。ストアドプロシージャは、あらかじめ「データベースサーバ上に」用意されたSQL命令セットのことです。データベースサーバ上ですでに最適化されているので、実行に際してあらためて「解析→コンパイル」などの処理が発生することはありません。また、アプリケーションサーバとデータベースサーバとが別々のマシンの場合でも、パラメータの受け渡しだけで複雑なSQL命令がネットワーク上を行き来しないので、ネットワークによるボトルネックが発生する危険性を抑えることができます。
解説
ストアドプロシージャは、CallableStatementクラスによって利用することができます。以下は、このCallableStatementクラスの使用例です。
package to.msn.wings; import java.io.IOException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CallableSql extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { Connection db=null; CallableStatement objSql=null; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); db = DriverManager.getConnection("jdbc:odbc:sample", "usr", "pass"); objSql = db.prepareCall("{call InsertBook (?,?,?)}"); objSql.setString(1,"ISBN 4-7981-0439-6"); objSql.setString(2,"10日でおぼえるJakarta入門教室"); objSql.setString(3,"2800"); objSql.executeUpdate(); } catch (ClassNotFoundException e) { throw new ServletException(e); } catch (SQLException e) { throw new ServletException(e); } finally{ try { if(objSql!=null){objSql.close();} if(db!=null){db.close();} } catch (SQLException se) { throw new ServletException(se); } } } }
注意:使用しているデータベースサーバやバージョンによっては、CallableStatementクラス(ストアドプロシージャ)を利用できない場合もあるので注意してください。例えば、MySQL 4.0.xではストアドプロシージャの機能は提供されていません。
ストアドプロシージャInsertBookは、ISBNコード、書名、価格をパラメータとして受け取り、新規レコードを追加するためのものとします。ストアドプロシージャを呼び出す際は、以下のような構文を利用します。
{call ストアドプロシージャ名 (?,...)}
全体を{call 〜}で囲み、ストアドプロシージャ名とパラメータの数だけプレイスホルダである“?”を列記します。もしも、出力パラメータが存在する場合は、以下のように記述することも可能です。
{?=call ストアドプロシージャ名 (?,...)}
注意:サーブレットクラスの動作にはデプロイメント・ディスクリプタ(web.xml)への登録が必須です。web.xmlへの設定については、連載:基礎から学ぶサーブレット/JSP(11)「JSPとサーブレットの違いを明らかにする」を参照してください。
Copyright © ITmedia, Inc. All Rights Reserved.