2012-08-31 3 views
0

이지만, 자바 닌자의 점 하나는 영리 해킹이 알고있을 경우 궁금해 ... 더 구체적으로 내 문제는 내가 추출 할 수있는 자동화를 만들기 위해 노력하고있다가/복원 다른 데이터 형식 (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; 
     } 
    } 
} 
+0

명세서를 실행하기 전에 확인하지 않으시겠습니까? 당신은'DatabaseMetaData.getDatabaseProductName()를 통해 공급 업체의 이름을 얻을' –

+0

@a_horse_with_no_name, 그는 그가, 난 그냥 java.sql의 API를 ... 오히려 혼란 답변에 의견을 변환하고 나는 그것을 표시 것 ... 발견했다. 고마워. – Lucas

답변

3

.

그런 식으로 예외를 "분석"할 필요가 없습니다.

관련 문제