더이지만, 자바 닌자의 점 하나는 영리 해킹이 알고있을 경우 궁금해 ... 더 구체적으로 내 문제는 내가 추출 할 수있는 자동화를 만들기 위해 노력하고있다가/복원 다른 데이터 형식 (xml, 다른 데이터베이스 공급 업체, json ...)에서 데이터베이스. 벤더 특정 코드의 범위를 *Adapter
클래스로 제한하려고합니다. 인터페이스는 다음과 같습니다SQLException으로부터 어떤 데이터베이스 공급 업체가 사용되는지 확인할 수 있습니까? 나는 간단한 대답을 믿고있어
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
에서 그것을 찾아 낼 가능성이 높습니다. 아직 그것을 알아 내지 못했습니다.
---------------------- UPDATE ----------------------- ----
를이 코드 내 목표를 달성 할 수 있었다 : 당신은DatabaseMetaData.getDatabaseProductName()
을 사용하여 데이터베이스 공급 업체의 이름을 확인할 수 있습니다 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;
}
}
}
명세서를 실행하기 전에 확인하지 않으시겠습니까? 당신은'DatabaseMetaData.getDatabaseProductName()를 통해 공급 업체의 이름을 얻을' –
@a_horse_with_no_name, 그는 그가, 난 그냥 java.sql의 API를 ... 오히려 혼란 답변에 의견을 변환하고 나는 그것을 표시 것 ... 발견했다. 고마워. – Lucas