1.2.3 アプリケーションが実行したSQLの自動取得
SQL出力機能
SQL出力機能は、サーブレット/JSPを使用して作られたWebアプリケーションが実行するSQLをHSIC-ECDエビデンスファイルに出力します。これによりアプリケーションが正しいSQLを実行しているかを確認できます。
HSIC-ECDは、JDBCドライバを使用してサーブレット/JSPが実行したSQLの実行メソッドをフックし、そのSQLをHSIC-ECDエビデンスファイルに出力します。
HSIC-ECDを使用するとテスト対象のアプリケーションが実行したSQL実行前後のデータ、または更新系SQL実行前後のデータを、テスト対象のアプリケーションを改造しないで取得できます。HSIC-ECDは、アプリケーションが実行したSQLの前後にSELECT文を実行して実行前後のデータを自動的に取得します。これによって、SQL実行結果をテストエビデンスとして取得するために手動、または専用のスクリプトを記述してSQLを実行する作業が不要となり、テスト効率が向上します。HSIC-ECDは、APサーバに組み込んで使用します。Java/JSPアプリケーションが実行するSQLがエビデンスの取得対象となります。また、SQL以外にもJavaアプリケーションの任意のメソッド実行時の引数などの情報をテストエビデンスとして取得できます。
SQL出力機能が対応しているJDBCドライバを次の表に示します。
DB名とバージョン |
JDBCドライバのファイル名 |
---|---|
HiRDB V9 |
pdjdbc4.jar |
Oracle Database 11g R2 |
ojdbc6.jar |
Oracle Database 12c |
ojdbc6.jar ojdbc7.jar |
DB2 10.5 DB2 11.1 |
db2jcc.jar db2jcc4.jar |
SQL Server 2016 Microsoft JDBC Driver 6.0 for SQL Server |
Sqljdbc4.jar Sqljdbc41.jar Sqljdbc42.jar |
SQL出力機能が対応しているAPサーバとDBの組み合わせを次の表に示します。
APサーバ |
DB名とバージョン |
---|---|
uCosminexus Application Server |
HiRDB V9 Oracle Database 11g R2 Oracle Database 12c |
WebSphere Application Server |
DB2 10.5 DB2 11.1 SQL Server 2016 Microsoft JDBC Driver 6.0 for SQL Server |
SQL出力機能のSQL文の出力契機となる、インタフェースおよびメソッドを次の表に示します。
インタフェース名 |
メソッド名 |
サポート状況 |
|||
---|---|---|---|---|---|
Oracle |
HiRDB |
DB2 |
SQL Server |
||
java.sql.Statement |
execute(String sql) |
○ |
○ |
○ |
○ |
execute(String sql, int autoGeneratedKeys) |
○ |
- |
○ |
○ |
|
execute(String sql, int[] columnIndexes) |
○ |
- |
○ |
○ |
|
execute(String sql, String[] columnNames) |
○ |
- |
○ |
○ |
|
executeLargeUpdate(String sql) |
- |
- |
- |
○ |
|
executeLargeUpdate(String sql, int autoGeneratedKeys) |
- |
- |
- |
○ |
|
executeLargeUpdate(String sql, int[] columnIndexes) |
- |
- |
- |
○ |
|
executeLargeUpdate(String sql, String[] columnNames) |
- |
- |
- |
○ |
|
executeQuery(String sql) |
○ |
○ |
○ |
○ |
|
executeUpdate(String sql) |
○ |
○ |
○ |
○ |
|
executeUpdate(String sql, int autoGeneratedKeys) |
○ |
- |
○ |
○ |
|
executeUpdate(String sql, int[] columnIndexes) |
○ |
- |
○ |
○ |
|
executeUpdate(String sql, String[] columnNames) |
○ |
- |
○ |
○ |
|
java.sql.PreparedStatement |
execute() |
○ |
○ |
○ |
○ |
executeLargeUpdate() |
- |
- |
- |
○ |
|
executeQuery() |
○ |
○ |
○ |
○ |
|
executeUpdate() |
○ |
○ |
○ |
○ |
|
java.sql.Statementから継承されたメソッド |
継承元と同じ |
- |
継承元と同じ |
||
java.sql.CallableStatement |
java.sql.Statementから継承されたメソッド |
継承元と同じ |
- |
継承元と同じ |
|
java.sql.PreparedStatementから継承されたメソッド |
継承元と同じ |
○ |
継承元と同じ |
- (凡例)
-
○:サポートしています。
-:サポートしていません。
また、SQL出力機能が対応しているsetterを次の表に示します。
- メモ
-
対応しているsetterは、SQL情報で出力するバインド変数にsetterで設定した値を文字列に置換して出力します。対応していないsettetrが使用されている場合は、文字列に置換しないで、バインド変数名をそのまま出力します。また、対応していないsettetrが使用されている場合は、後述するDB更新前後情報出力機能、およびSQL参照情報出力機能で正しい情報を出力できないことがあります。
インタフェース名 |
メソッド名 |
サポート状況 |
|||
---|---|---|---|---|---|
Oracle |
HiRDB |
DB2 |
SQL Server |
||
java.sql.PreparedStatement |
setBigDecimal(int parameterIndex, BigDecimal x) |
○ |
○ |
○ |
○ |
setBoolean(int parameterIndex, boolean x) |
○ |
○ |
○ |
○ |
|
setByte(int parameterIndex, byte x) |
○ |
○ |
○ |
○ |
|
setBytes(int parameterIndex, byte[] x) |
○ |
○ |
○ |
○ |
|
setDate(int parameterIndex, Date x) |
○ |
○ |
○ |
○ |
|
setDate(int parameterIndex, Date x, Calendar cal) |
○ |
○ |
○ |
○ |
|
setDouble(int parameterIndex, double x) |
○ |
○ |
○ |
○ |
|
setFloat(int parameterIndex, float x) |
○ |
○ |
○ |
○ |
|
setInt(int parameterIndex, int x) |
○ |
○ |
○ |
○ |
|
setLong(int parameterIndex, long x) |
○ |
○ |
○ |
○ |
|
setNString(int parameterIndex, String value) |
○ |
- |
- |
○ |
|
setNull(int parameterIndex, int sqlType) |
○ |
○ |
○ |
○ |
|
setNull(int parameterIndex, int sqlType, String typeName) |
○ |
- |
- |
○ |
|
setRowId(int parameterIndex, RowId x) |
○ |
- |
- |
- |
|
setShort(int parameterIndex, short x) |
○ |
○ |
○ |
○ |
|
setString(int parameterIndex, String x) |
○ |
○ |
○ |
○ |
|
setTime(int parameterIndex, Time x) |
○ |
○ |
○ |
○ |
|
setTime(int parameterIndex, Time x, Calendar cal) |
○ |
○ |
○ |
○ |
|
setTimestamp(int parameterIndex, Timestamp x) |
○ |
○ |
○ |
○ |
|
setTimestamp(int parameterIndex, Timestamp x, Calendar cal) |
○ |
○ |
○ |
○ |
|
setURL(int parameterIndex, URL x) |
○ |
- |
○ |
- |
|
java.sql.CallableStatement |
java.sql.PreparedStatementから継承されたメソッド |
継承元と同じ |
|||
setBigDecimal(String parameterName, BigDecimal x) |
○ |
○ |
○ |
○ |
|
setBoolean(String parameterName, boolean x) |
○ |
○ |
○ |
○ |
|
setByte(String parameterName, byte x) |
○ |
○ |
○ |
○ |
|
setBytes(String parameterName, byte[] x) |
○ |
○ |
○ |
○ |
|
setDate(String parameterName, Date x) |
○ |
○ |
○ |
○ |
|
setDate(String parameterName, Date x, Calendar cal) |
○ |
○ |
○ |
○ |
|
setDouble(String parameterName, double x) |
○ |
○ |
○ |
○ |
|
setFloat(String parameterName, float x) |
○ |
○ |
○ |
○ |
|
setInt(String parameterName, int x) |
○ |
○ |
○ |
○ |
|
setLong(String parameterName, long x) |
○ |
○ |
○ |
○ |
|
setNString(String parameterName, String value) |
- |
- |
- |
○ |
|
setNull(String parameterName, int sqlType) |
○ |
○ |
○ |
○ |
|
setNull(String parameterName, int sqlType, String typeName) |
○ |
- |
- |
○ |
|
setRowId(String parameterName, RowId x) |
○ |
- |
- |
- |
|
setShort(String parameterName, short x) |
○ |
○ |
○ |
○ |
|
setString(String parameterName, String x) |
○ |
○ |
○ |
○ |
|
setTime(String parameterName, Time x) |
○ |
○ |
○ |
○ |
|
setTime(String parameterName, Time x, Calendar cal) |
○ |
○ |
○ |
○ |
|
setTimestamp(String parameterName, Timestamp x) |
○ |
○ |
○ |
○ |
|
setTimestamp(String parameterName, Timestamp x, Calendar cal) |
○ |
○ |
○ |
○ |
|
setURL(String parameterName, URL x) |
○ |
- |
○ |
- |
|
OraclePreparedStatement |
setBigDecimalAtName(String parameterName, BigDecimal value) |
○ |
- |
- |
- |
setBigDecimalAtName(String parameterName, BigDecimal value) |
○ |
- |
- |
- |
|
setBinaryDouble(int parameterIndex, BINARY_DOUBLE value) |
○ |
- |
- |
- |
|
setBinaryDouble(int parameterIndex, double value) |
○ |
- |
- |
- |
|
setBinaryDoubleAtName(String parameterName, BINARY_DOUBLE value) |
○ |
- |
- |
- |
|
setBinaryDoubleAtName(String parameterName, double value) |
○ |
- |
- |
- |
|
setBinaryFloat(int parameterIndex, BINARY_FLOAT value) |
○ |
- |
- |
- |
|
setBinaryFloat(int parameterIndex, float value) |
○ |
- |
- |
- |
|
setBinaryFloatAtName(String parameterName, BINARY_FLOAT value) |
○ |
- |
- |
- |
|
setBinaryFloatAtName(String parameterName, float value) |
○ |
- |
- |
- |
|
setBooleanAtName(String parameterName, boolean value) |
○ |
- |
- |
- |
|
setByteAtName(String parameterName, byte value) |
○ |
- |
- |
- |
|
setBytesAtName(String parameterName, byte[] value) |
○ |
- |
- |
- |
|
setCHAR(int parameterIndex, CHAR ch) |
○ |
- |
- |
- |
|
setCHARAtName(String parameterName, CHAR value) |
○ |
- |
- |
- |
|
setDATE(int parameterIndex, DATE date) |
○ |
- |
- |
- |
|
setFloatAtName(String parameterName, float value) |
○ |
- |
- |
- |
|
setIntAtName(String parameterName, int value) |
○ |
- |
- |
- |
|
setLongAtName(String parameterName, long value) |
○ |
- |
- |
- |
|
setNStringAtName(String parameterName, String value) |
○ |
- |
- |
- |
|
setNullAtName(String parameterName, int sqlType) |
○ |
- |
- |
- |
|
setNullAtName(String parameterName, int sqlType, String sqlName) |
○ |
- |
- |
- |
|
setNUMBER(int parameterIndex, NUMBER num) |
○ |
- |
- |
- |
|
setNUMBERAtName(String parameterName, NUMBER value) |
○ |
- |
- |
- |
|
setROWID(int parameterIndex, ROWID rowid) |
○ |
- |
- |
- |
|
setRowIdAtName(String parameterName, RowId value) |
○ |
- |
- |
- |
|
setROWIDAtName(String parameterName, ROWID value) |
○ |
- |
- |
- |
|
setShortAtName(String parameterName, short value) |
○ |
- |
- |
- |
|
setSQLXMLAtName(String parameterName, SQLXML value) |
× |
- |
- |
- |
|
setStringAtName(String parameterName, String value) |
○ |
- |
- |
- |
|
setTimeAtName(String parameterName, Time value) |
○ |
- |
- |
- |
|
setTimeAtName(String parameterName, Time value, Calendar cal) |
○ |
- |
- |
- |
|
setTIMESTAMP(int parameterIndex, TIMESTAMP x) |
○ |
- |
- |
- |
|
setTimestampAtName(String parameterName, Timestamp value) |
○ |
- |
- |
- |
|
setTIMESTAMPAtName(String parameterName, TIMESTAMP value) |
○ |
- |
- |
- |
|
setTimestampAtName(String parameterName, Timestamp value, Calendar cal) |
○ |
- |
- |
- |
|
setTIMESTAMPLTZ(int parameterIndex, TIMESTAMPLTZ x) |
○ |
- |
- |
- |
|
setTIMESTAMPLTZAtName(String parameterName, TIMESTAMPLTZ value) |
○ |
- |
- |
- |
|
setTIMESTAMPTZ(int parameterIndex, TIMESTAMPTZ x) |
○ |
- |
- |
- |
|
setTIMESTAMPTZAtName(String parameterName, TIMESTAMPTZ value) |
○ |
- |
- |
- |
|
setURLAtName(String parameterName, URL value) |
○ |
- |
- |
- |
|
OracleCallableStatement |
OraclePreparedStatementから継承されたメソッド |
継承元と同じ |
- |
- |
- |
setBinaryDouble(String parameterName, BINARY_DOUBLE x) |
○ |
- |
- |
- |
|
setBinaryDouble(String parameterName, double x) |
○ |
- |
- |
- |
|
setBinaryFloat(String parameterName, BINARY_FLOAT x) |
○ |
- |
- |
- |
|
setBinaryFloat(String parameterName, float x) |
○ |
- |
- |
- |
|
setCHAR(String parameterName, CHAR x) |
○ |
- |
- |
- |
|
setDATE(String parameterName, DATE x) |
○ |
- |
- |
- |
|
setFixedCHAR(String parameterName, String x) |
○ |
- |
- |
- |
|
setNUMBER(String parameterName, NUMBER x) |
○ |
- |
- |
- |
|
setROWID(String parameterName, ROWID x) |
○ |
- |
- |
- |
|
setTIMESTAMP(String parameterName, TIMESTAMP x) |
○ |
- |
- |
- |
|
setTIMESTAMPLTZ(String parameterName, TIMESTAMPLTZ x) |
○ |
- |
- |
- |
|
setTIMESTAMPTZ(String parameterName, TIMESTAMPTZ x) |
○ |
- |
- |
- |
|
SQLServerPreparedStatement |
setDateTime(int n, Timestamp x) |
- |
- |
- |
○(※) |
setDateTimeOffset(int n, DateTimeOffset x) |
- |
- |
- |
○ |
|
setMoney(int n, BigDecimal x) |
- |
- |
- |
○(※) |
|
setSmallDateTime(int n, Timestamp x) |
- |
- |
- |
○(※) |
|
setSmallMoney(int,BigDecimal x) |
- |
- |
- |
○(※) |
|
setUniqueIdentifier(int n, String x) |
- |
- |
- |
○(※) |
|
SQLServerCallableStatement |
setDateTime(String sCol, Timestamp x) |
- |
- |
- |
○(※) |
setDateTimeOffset(String sCol, DateTimeOffset x) |
- |
- |
- |
○ |
|
setMoney(String sCol, BigDecimal b) |
- |
- |
- |
○(※) |
|
setSmallDateTime(String sCol, Timestamp t) |
- |
- |
- |
○(※) |
|
setSmallMoney(String sCol, BigDecimal d) |
- |
- |
- |
○(※) |
|
setUniqueIdentifier(String sCol, String s) |
- |
- |
- |
○(※) |
- (凡例)
-
○:サポートしています。
-:サポートしていません。
注※:sqljdbc4.jarではサポートしていません。
- 注意事項
-
-
SQL実行中に例外が発生した場合は、実行したSQLを出力できないことがあります。
-
アプリケーションサーバが自動で定期的に実行するSQLは、HSIC-ECDエビデンスファイルに出力しません。
-
Webアプリケーションが発行するSQL文に付随してJDBCドライバが発行するSQL文も、HSIC-ECDエビデンスファイルに出力します。
-
エスケープ句を使用した場合、エスケープ処理後のSQL文を出力することがあります。
-
DB更新前後情報出力機能
DB更新前後情報出力機能は、SQL出力機能で出力したSQL文が更新系SQLの場合、更新前後のデータベースのデータを出力します。
更新前情報の取得対象となるSQL文はUPDATE文とDELETE文です。
更新後情報の取得対象となるSQL文はUPDATE文とINSERT文です。
DB種別に依存しない注意事項
エビデンスファイルに出力する情報は、commitされていることを保証するものではありません。
カーソルを使用した更新(Resultsetクラスのupdaterメソッド)をした場合は、SQLの更新前後情報はエビデンスファイルには出力されません。
取得した列の値を、toString()で文字列に変換して出力します。抽象データ型、BLOB型,CLOB型,BFILE型などtoString()で文字列に変換できない型が使用された場合は<型名>を出力します。
取得した列の値がnull値の場合は、<null>を出力します。
ストアドプロシージャを実行した場合、ストアドプロシージャの実行を示すCALL、またはEXCUTEがエビデンスファイルに出力されます。ストアドプロシージャの内部で実行している処理はエビデンスファイルに出力されません。
HSICが対応していない構文で書かれたSQL文が実行された場合は、エビデンスファイルにはKFSF50002-Wを出力します。
乱数や現在時刻を取得するファンクションを使用している場合は、正しい更新前後情報を取得できません。
表の内容を更新するようなファンクションを実行している場合の動作は保証しません。HSICが実行するSQLでファンクションが実行されたときに、アプリケーションが意図しない表を更新することがあります。
SQL文中の「--」から行末まではコメントと見なします。
WHERE句の条件判定に使う列の値を更新する場合、更新後情報が正しく出力されないことがあります。
DBがHiRDBの場合の注意事項
共用表を使用していて、ほかのアプリケーションがLOCK文で共用表を排他していると、HISCが実行するSQL、またははLOCK文の実行がエラーになる場合があります。
HSICが実行するSQL文の排他オプションには、WITHOUT LOCK NOWAITを指定して実行します。
INSERT文にVALUES句、およびDEFAULT VALUES句が指定された場合は更新後情報を出力しません。
次に示す句、または構文を使用したSQL文には対応していません(更新前後情報を出力しません)。
-
WHERE CURRENT OF句
-
NEXT VALUE式
-
UPDATE文でSET ROW、ADD、DELETEのどれかを使う更新
-
INSERT文で(ROW)を指定した行挿入
DBがOracleの場合の注意事項
SQL文のテーブル名などに予約語ではないSQLキーワードを使用しないでください。使用している場合は、更新前後情報を取得するためにHSICが不正なSQL文を発行するおそれがあります。なお、予約語とキーワードの詳細については、Oracleのドキュメントを参照してください。
INSERT文にVALUES句が指定された場合は、DUAL表に対してSELECT文を実行して更新後情報を取得します。
INSERT文のVALUES句にDEFAULTと指定した場合は、更新後情報には定義されたデフォルト値ではなく、'DEFAULT'を出力します。
INSERT文でダイレクト、パス、またはインサートを使用する場合は、自動コミットを有効にしてください。無効にした場合は、更新後情報を取得できません。
次に示す句、または構文を使用したSQL文には対応していません(更新前後情報を出力しません)。
-
WHERE CURRENT OF
-
順序値NEXTVAL(※)
注※:NEXTVALを列名や表名として使用した場合も、更新前後情報を出力しません。
-
UPDATE文のVALUE句
DBがDB2の場合の注意事項
HSICが実行するSQL文には、FOR READ ONLY WITH URを指定して実行します。
二重引用符で囲まれた識別子内の「""」は、「"」一つとして扱います。
数値の小数点は常にピリオドとして扱います。
SQL文のテーブル名などにSQLの文法上意味を持つキーワード(例:PORTION、UR)を使用しないでください。使用している場合は、更新前後情報を取得するためにHSICが不正なSQL文を発行するおそれがあります。
SELECT文のFROM句にINSERT、DELETE、またはUPDATE文を指定して更新処理をした場合、更新前後情報を取得しません。
アプリケーションが、構造化タイプを使用した列を更新した場合、更新前後情報の取得に失敗することがあります。
INSERT文にVALUES句が指定された場合は、SYSIBM.SYSDUMMY1表に対してSELECT文を実行して更新後情報を取得します。
INSERT文のVALUES句にDEFAULTと指定した場合は、更新後情報には定義されたデフォルト値ではなく、'DEFAULT'と出力します。
隠し列として定義した列の値は、DELETE文の更新前情報に出力しません。
次に示す句、または構文を使用したSQL文には対応していません(更新前後情報を出力しません)。
-
WHERE CURRENT OF句
-
NEXT VALUE式
-
INCLUDE句
-
UPDATE文のFROM句
DBがSQL Serverの場合の注意事項
HSICが実行するSQL文では、前後情報を取得する対象のテーブル名にテーブルヒントとしてWITH(READUNCOMMITTED、NOWAIT)を指定して実行します。
SQL文のテーブル名などにSQLの文法上意味を持つキーワード(例:STATISTICSなど)を使用している場合は、更新前後情報を取得するためにHSICが不正なSQL文を発行するおそれがあります。
アプリケーションが、ユーザ定義テーブル型を使用した列を更新すると、更新前後情報の取得時に誤った情報を取得することがあります。
INSERT文のVALUES句にDEFAULTと指定した場合は、更新後情報には定義されたデフォルト値ではなく、'DEFAULT'と出力します。ただし、VALUES句で複数行挿入する場合にDEFAULTと指定した場合は、更新後情報を出力しません。
INSERT文でDEFAULT VALUES句を使用した場合は、更新後情報には定義されたデフォルト値ではなく、'DEFAULT VALUES'と出力します
INSERT文でVALUES句とTOP句を同時に使用する場合に、TOP句で定数値以外を指定しているときは更新後情報を出力しません。
JDBCドライバのSQL Serverへの接続プロパティで、sendTimeAsDatetimeがtrue(デフォルト値)となっている場合に、setTime関数を使用すると、更新前後情報でtime型の値がdatetime型として取得され、'1970-01-01'が付加されることがあります。
次に示す句、または構文を使用したSQL文には対応していません(更新前後情報を出力しません)。
-
WHERE CURRENT OF句
-
NEXT VALUE式
-
OUTPUT句を使用した構文を含むINSERT文
-
EXECまたはEXECUTEを含むINSERT文
-
UPDATE文のFROM句
-
DELETE文の追加のFROM句
-
READTEXT句
-
UPDATETEXT句
-
WRITETEXT句