簡単な答えはノーだと思いますが、そこにいるJava忍者の1人が巧妙なハックを知っているのではないかと思います...より具体的には、私の問題は、他のデータベースからデータベースを抽出/復元できる自動化を作成しようとしていることですデータ形式(xml、別のデータベースベンダー、json ...)。ベンダー固有のコードの範囲を*Adapter
クラスに制限しようとしています。インターフェイスは次のとおりです。
public String escapeName( String name );
public ColumnMetaData columnMetaDataFromResultSet( ResultSet resultSet ) throws SQLException;
public SqlQuery getColumnMetaDataSql( String schema, String table );
public String getCreateTableSql( TableMetaData tableMetaData );
public String getDropTableSql( TableMetaData tableMetaData );
public String getRowInsertSql( TableMetaData tableMetaData );
public String getRowSelectSql( TableMetaData tableMetaData );
public SqlQuery getTableMetaDataSql();
public TableMetaData tableMetaDataFromResultSet( ResultSet resultSet ) throws SQLException;
この質問に対する重要な方法はgetDropTableSql( TableMetaData tableMetaData )
です。そのメソッドは、理論的には、メタデータによって示されるテーブルを削除して再作成できるようにするSQLステートメントを返します(これは、完全なデータセットを定期的に公開するために使用されるため、古いものから新しいものへ)。MySQLとSQLServerの両方のアダプターは、安全なDROP
(DROP table IF EXISTS
または同様の)フレーバーをサポートしていますが、OracleとDB2はサポートしていません。それで、私の次の考えは、それをドロップして適切な例外をキャッチすることでした。しかし、スローされる例外はjava.sql.SQLSyntaxErrorException
(またはorg.springframework.jdbc.BadSqlGrammarException
私がスプリングを使用しているため)JdbcTemplate
)。その例外のファミリーは、安全にキャッチするには広範に思えます(そして、それは私には実際には文法のようには見えません...)。各ベンダーは異なるSQLStateとErrorCodeを返すように見えるので、ベンダーを特定できない限り、これらはあまり役に立ちません。私も?春はどういうわけかそれをしていることを私は知っています、おそらくそれをDataSource
クエリを発行したものから掘り下げることによって。まだ理解していません。
- - - - - - - - - - - アップデート - - - - - - - - - - - - - -
私はこのコードで私の目標を達成することができました:
private void dropTable( JdbcTemplate jdbcTemplate, String dropSql ) {
try {
jdbcTemplate.execute( dropSql );
}
catch ( BadSqlGrammarException sqle ) {
try {
throw sqle.getRootCause();
}
catch ( SQLException rootCause ) {
int errorCode = rootCause.getErrorCode();
String sqlState = rootCause.getSQLState();
try {
String vendor = jdbcTemplate.getDataSource().getConnection().getMetaData().getDatabaseProductName();
if ( vendor.equalsIgnoreCase( "mysql" ) && errorCode == 1051 && sqlState.equals( "42S02" ) ) {
logger.info( "mysql table does not exist, unable to drop ({})", dropSql );
}
else if ( vendor.equalsIgnoreCase( "oracle" ) && errorCode == 942 && sqlState.equals( "42000" ) ) {
logger.info( "oracle table does not exist, unable to drop ({})", dropSql );
}
else {
throw( sqle );
}
}
catch ( Exception e ) {
throw( sqle );
}
}
catch ( Throwable e ) {
throw sqle;
}
}
}