プリペアードステートメント
| 日本語 | 準備済み命令文 |
| 英語 | prepared statement |
| ふりがな | ぷりぺあーどすてーとめんと |
| フリガナ | プリペアードステートメント |
あらかじめ準備されたSQL。
複数のSQLを実行する場合に、検索条件や更新する値のみが異なる場合に、その値をパラメーター化し、SQLを使い回すことができる。このようなSQLを「プリペアードステートメント」と言う。
プリペアードステートメントは、パラメーター化する箇所を「?」(ハテナマーク)で記述する。SELECTの場合には「SELECT 列名, ... FROM テーブル名 WHERE 列名 = ?」のような形式にする。SQL実行時に「?」に「100」という値をセットした場合には「SELECT 列名, ... FROM テーブル名 WHERE 列名 = 100」というSQLが作られ実行されることになる。
JDBCを使用する場合、プリペアードステートメントは、ConnectionインターフェイスのprepareStatement()メソッドでSQLを指定して作成する。
このメソッドの戻り値としてPreparedStatementインターフェイスのインスタンスが返され、このインターフェイスを使用してSQLを実行する。
?への値のセットは、PreparedStatementインターフェイスのsetInt()等のメソッドを使用する。第1引数には?のインデックスナンバーを指定する。ただし、インデックスナンバーは1から始まる。配列等と異なるため注意。第2引数にセットする値を指定する。
プリペアードステートメントは、SQLを毎回作らないため処理速度が速くなる。
だが、JDBCを使用する場合、むしろSQLインジェクションを防ぐために使用される。逆に言うと、画面から入力された値を検索条件にするような場合には、決してStatementインターフェイスを使用してはならない。
複数のSQLを実行する場合に、検索条件や更新する値のみが異なる場合に、その値をパラメーター化し、SQLを使い回すことができる。このようなSQLを「プリペアードステートメント」と言う。
プリペアードステートメントは、パラメーター化する箇所を「?」(ハテナマーク)で記述する。SELECTの場合には「SELECT 列名, ... FROM テーブル名 WHERE 列名 = ?」のような形式にする。SQL実行時に「?」に「100」という値をセットした場合には「SELECT 列名, ... FROM テーブル名 WHERE 列名 = 100」というSQLが作られ実行されることになる。
JDBCを使用する場合、プリペアードステートメントは、ConnectionインターフェイスのprepareStatement()メソッドでSQLを指定して作成する。
このメソッドの戻り値としてPreparedStatementインターフェイスのインスタンスが返され、このインターフェイスを使用してSQLを実行する。
?への値のセットは、PreparedStatementインターフェイスのsetInt()等のメソッドを使用する。第1引数には?のインデックスナンバーを指定する。ただし、インデックスナンバーは1から始まる。配列等と異なるため注意。第2引数にセットする値を指定する。
プリペアードステートメントは、SQLを毎回作らないため処理速度が速くなる。
だが、JDBCを使用する場合、むしろSQLインジェクションを防ぐために使用される。逆に言うと、画面から入力された値を検索条件にするような場合には、決してStatementインターフェイスを使用してはならない。
// Sample.java
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Sample
{
public static void main( String[] args )
{
Connection conn = null;
PreparedStatement psCreate = null;
PreparedStatement psInsert = null;
PreparedStatement psSelect = null;
ResultSet rs = null;
try
{
// この使用例の使用方法についてはSQLの項目を参照してください。
// JDBCドライバをロードします。
Class.forName( "org.hsqldb.jdbcDriver" );
// コネクションを取得します。
String url = "jdbc:hsqldb:mem:aname";
String user = "sa";
String password = "";
conn = DriverManager.getConnection( url, user, password );
// テーブルを作ります。
psCreate = null;
final String SQL_CREATE = "CREATE TABLE TABLE_TEST( NAME VARCHAR, VALUE INT );";
psCreate = conn.prepareStatement( SQL_CREATE );
psCreate.execute();
// 行を追加します。
// セットする値は直接記述せず、?にしておきます。
// この?になっているSQLがプリペアードステートメントです。
final String SQL_INSERT = "INSERT INTO TABLE_TEST VALUES( ?, ? );";
// プリペアードステートメントは、Connectionインターフェイスの
// prepareStatement()メソッドでPreparedStatementインターフェイスの
// インスタンスを作って、これを使って操作します。
psInsert = conn.prepareStatement( SQL_INSERT );
for( int iF1 = 0; iF1 < 3; ++iF1 )
{
// ?に値をセットします。
// 列の指定は、インデックスナンバーで行います。
// 1から始まるので注意。
psInsert.setString( 1, "ネーム" + iF1 );
psInsert.setInt( 2, iF1 );
// execute()メソッドでSQLを実行して、行を追加します。
psInsert.execute();
}
// 検索します。その際、WHEREで絞り込みを行います。
// 絞り込みに使用する値はセットせず、?にしておきます。
final String SQL_SELECT = "SELECT NAME, VALUE FROM TABLE_TEST WHERE NAME = ?;";
// INSERTの時と同じく、?に値をセットする場合には
// PreparedStatementインターフェイスを使用します。
psSelect = conn.prepareStatement( SQL_SELECT );
// ?に検索条件をセットします。
// これもインデックスナンバーは1から始まるので注意してください。
psSelect.setString( 1, "ネーム1" );
// 検索します。
rs = psSelect.executeQuery();
while( rs.next() )
{
String name = rs.getString( "NAME" );
int value = rs.getInt( "VALUE" );
System.out.println( name + ", " + value );
}
// ネーム1, 1
}
catch( SQLException e )
{
// SQLの実行で問題があった場合に投げられます。
e.printStackTrace();
}
catch( ClassNotFoundException e )
{
// JDBCドライバが存在しなかった場合に投げられます。
e.printStackTrace();
}
finally
{
if( rs != null )
{
try
{
rs.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psSelect != null )
{
try
{
psSelect.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psInsert != null )
{
try
{
psInsert.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psCreate != null )
{
try
{
psCreate.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( conn != null )
{
try
{
conn.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
}
}
}
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Sample
{
public static void main( String[] args )
{
Connection conn = null;
PreparedStatement psCreate = null;
PreparedStatement psInsert = null;
PreparedStatement psSelect = null;
ResultSet rs = null;
try
{
// この使用例の使用方法についてはSQLの項目を参照してください。
// JDBCドライバをロードします。
Class.forName( "org.hsqldb.jdbcDriver" );
// コネクションを取得します。
String url = "jdbc:hsqldb:mem:aname";
String user = "sa";
String password = "";
conn = DriverManager.getConnection( url, user, password );
// テーブルを作ります。
psCreate = null;
final String SQL_CREATE = "CREATE TABLE TABLE_TEST( NAME VARCHAR, VALUE INT );";
psCreate = conn.prepareStatement( SQL_CREATE );
psCreate.execute();
// 行を追加します。
// セットする値は直接記述せず、?にしておきます。
// この?になっているSQLがプリペアードステートメントです。
final String SQL_INSERT = "INSERT INTO TABLE_TEST VALUES( ?, ? );";
// プリペアードステートメントは、Connectionインターフェイスの
// prepareStatement()メソッドでPreparedStatementインターフェイスの
// インスタンスを作って、これを使って操作します。
psInsert = conn.prepareStatement( SQL_INSERT );
for( int iF1 = 0; iF1 < 3; ++iF1 )
{
// ?に値をセットします。
// 列の指定は、インデックスナンバーで行います。
// 1から始まるので注意。
psInsert.setString( 1, "ネーム" + iF1 );
psInsert.setInt( 2, iF1 );
// execute()メソッドでSQLを実行して、行を追加します。
psInsert.execute();
}
// 検索します。その際、WHEREで絞り込みを行います。
// 絞り込みに使用する値はセットせず、?にしておきます。
final String SQL_SELECT = "SELECT NAME, VALUE FROM TABLE_TEST WHERE NAME = ?;";
// INSERTの時と同じく、?に値をセットする場合には
// PreparedStatementインターフェイスを使用します。
psSelect = conn.prepareStatement( SQL_SELECT );
// ?に検索条件をセットします。
// これもインデックスナンバーは1から始まるので注意してください。
psSelect.setString( 1, "ネーム1" );
// 検索します。
rs = psSelect.executeQuery();
while( rs.next() )
{
String name = rs.getString( "NAME" );
int value = rs.getInt( "VALUE" );
System.out.println( name + ", " + value );
}
// ネーム1, 1
}
catch( SQLException e )
{
// SQLの実行で問題があった場合に投げられます。
e.printStackTrace();
}
catch( ClassNotFoundException e )
{
// JDBCドライバが存在しなかった場合に投げられます。
e.printStackTrace();
}
finally
{
if( rs != null )
{
try
{
rs.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psSelect != null )
{
try
{
psSelect.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psInsert != null )
{
try
{
psInsert.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psCreate != null )
{
try
{
psCreate.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( conn != null )
{
try
{
conn.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
}
}
}
// Sample.java
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Sample
{
public static void main( String[] args )
{
Connection conn = null;
PreparedStatement psCreate = null;
PreparedStatement psInsert = null;
PreparedStatement psSelect = null;
ResultSet rs = null;
try
{
// この使用例の使用方法についてはSQLの項目を参照してください。
// JDBCドライバをロードします。
Class.forName( "org.hsqldb.jdbcDriver" );
// コネクションを取得します。
String url = "jdbc:hsqldb:mem:aname";
String user = "sa";
String password = "";
conn = DriverManager.getConnection( url, user, password );
// テーブルを作ります。
psCreate = null;
final String SQL_CREATE = "CREATE TABLE TABLE_TEST( NAME VARCHAR, VALUE INT );";
psCreate = conn.prepareStatement( SQL_CREATE );
psCreate.execute();
// 行を追加します。
// セットする値は直接記述せず、?にしておきます。
// この?になっているSQLがプリペアードステートメントです。
final String SQL_INSERT = "INSERT INTO TABLE_TEST VALUES( ?, ? );";
// プリペアードステートメントは、Connectionインターフェイスの
// prepareStatement()メソッドでPreparedStatementインターフェイスの
// インスタンスを作って、これを使って操作します。
psInsert = conn.prepareStatement( SQL_INSERT );
for( int iF1 = 0; iF1 < 3; ++iF1 )
{
// ?に値をセットします。
// 列の指定は、インデックスナンバーで行います。
// 1から始まるので注意。
psInsert.setString( 1, "ネーム" + iF1 );
psInsert.setInt( 2, iF1 );
// execute()メソッドでSQLを実行して、行を追加します。
psInsert.execute();
}
// 検索します。その際、WHEREで絞り込みを行います。
// 絞り込みに使用する値はセットせず、?にしておきます。
final String SQL_SELECT = "SELECT NAME, VALUE FROM TABLE_TEST WHERE NAME = ?;";
// INSERTの時と同じく、?に値をセットする場合には
// PreparedStatementインターフェイスを使用します。
psSelect = conn.prepareStatement( SQL_SELECT );
// ?に検索条件をセットします。
// これもインデックスナンバーは1から始まるので注意してください。
psSelect.setString( 1, "ネーム1" );
// 検索します。
rs = psSelect.executeQuery();
while( rs.next() )
{
String name = rs.getString( "NAME" );
int value = rs.getInt( "VALUE" );
System.out.println( name + ", " + value );
}
// ネーム1, 1
}
catch( SQLException e )
{
// SQLの実行で問題があった場合に投げられます。
e.printStackTrace();
}
catch( ClassNotFoundException e )
{
// JDBCドライバが存在しなかった場合に投げられます。
e.printStackTrace();
}
finally
{
if( rs != null )
{
try
{
rs.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psSelect != null )
{
try
{
psSelect.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psInsert != null )
{
try
{
psInsert.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psCreate != null )
{
try
{
psCreate.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( conn != null )
{
try
{
conn.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
}
}
}




