プリペアードステートメント
日本語 | 準備済み命令文 |
英語 | 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(); } } } } }