2011-04-12 73 views
5

我想從Java代碼(使用基本的JDBC)檢索我的Oracle數據庫的不同類型的元數據。例如,如果我想與_FOO後綴檢索表的列表,我可以這樣做:如何從JDBC檢索序列元數據?

Connection connection = dataSource.getConnection(); 
DatabaseMetaData meta = connection.getMetaData(); 
ResultSet tables = meta.getTables(connection.getCatalog(), null, "%_FOO", new String[] { "TABLE" }); 
// Iterate on the ResultSet to get information on tables... 

現在,我想從我的數據庫檢索所有序列(例如所有序列命名爲S_xxx_FOO )。

我將如何做到這一點,因爲我沒有看到DatabaseMetaData任何有關序列?

我一定要運行像select * from user_sequences查詢?

回答

3

您無法通過JDBC API做到這一點,因爲一些數據庫(仍然)不支持序列。

,讓他們的唯一方法是查詢您的DBMS(我想這是甲骨文在你的情況你提到user_sequences

+0

有關如何做到這一點的詳細信息,請參閱我的答案。 :-) – 2016-12-08 23:01:42

3

有同樣問題的系統目錄。這很容易。只需將「SEQUENCE」傳遞給getMetaData()。getTables()類型參數即可。

在特定情況下,它會是這樣的:

meta.getTables(connection.getCatalog(),NULL, 「%_Foo」,新的String [] { 「序列」});

+0

這不適用於將類型限制爲'SYNONYM','TABLE'和'VIEW'的odjbc5.jar和ojdbc6.jar驅動程序,如果使用其他方法調用則會引發異常。 – zigarn 2013-11-06 17:37:28

+0

它在ojdbc7驅動程序的12.1.0.1版本中正常工作,但在版本12.1.0.2中停止工作,因爲如您所說,現在它忽略了「types」參數中不屬於getTableTypes()返回的類型之一的任何內容。我在論壇上提出了一個問題,詢問這是否是有意的:https://community.oracle.com/message/14134247#14134247 – 2016-12-02 03:19:41

0

您可以使用Hibernate的方言API檢索序列名稱。見:http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/dialect/Dialect.html

從下面的例子,你可以看到如何使用方言來獲得序列名稱

public static void main(String[] args) { 
     Connection jdbcConnection = null; 
     try { 
      jdbcConnection = DriverManager.getConnection("", "", ""); 
      printAllSequenceName(jdbcConnection); 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 
      if(jdbcConnection != null) { 
       try { 
        jdbcConnection.close(); 
       } catch (SQLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
} 

public static void printAllSequenceName(Connection conn) throws JDBCConnectionException, SQLException { 
     DialectResolver dialectResolver = new StandardDialectResolver(); 
     Dialect dialect = dialectResolver.resolveDialect(conn.getMetaData()); 

     if (dialect.supportsSequences()) { 
      String sql = dialect.getQuerySequencesString(); 
      if (sql!=null) { 

       Statement statement = null; 
       ResultSet rs = null; 
       try { 
        statement = conn.createStatement(); 
        rs = statement.executeQuery(sql); 

        while (rs.next()) { 
         System.out.println("Sequence Name : " + rs.getString(1)); 
        } 
       } 
       finally { 
        if (rs!=null) rs.close(); 
        if (statement!=null) statement.close(); 
       } 

      } 
     } 
    } 

如果你不希望使用休眠,那麼你必須箱定製順序具體實施。對於自定義實現

示例代碼

interface SequenceQueryGenerator { 
    String getSelectSequenceNextValString(String sequenceName); 
    String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize); 
    String getDropSequenceStrings(String sequenceName); 
    String getQuerySequencesString(); 
} 


class OracleSequenceQueryGenerator implements SequenceQueryGenerator { 

    @Override 
    public String getSelectSequenceNextValString(String sequenceName) { 
     return "select " + getSelectSequenceNextValString(sequenceName) + " from dual"; 
    } 

    @Override 
    public String getCreateSequenceString(String sequenceName, 
      int initialValue, int incrementSize) { 
     return "create sequence " + sequenceName + " start with " + initialValue + " increment by " + incrementSize; 
    } 

    @Override 
    public String getDropSequenceStrings(String sequenceName) { 
     return "drop sequence " + sequenceName; 
    } 

    @Override 
    public String getQuerySequencesString() { 
     return "select sequence_name from user_sequences"; 
    } 

} 


class PostgresSequenceQueryGenerator implements SequenceQueryGenerator { 

    @Override 
    public String getSelectSequenceNextValString(String sequenceName) { 
     return "select " + getSelectSequenceNextValString(sequenceName); 
    } 

    @Override 
    public String getCreateSequenceString(String sequenceName, 
      int initialValue, int incrementSize) { 
     return "create sequence " + sequenceName + " start " + initialValue + " increment " + incrementSize; 
    } 

    @Override 
    public String getDropSequenceStrings(String sequenceName) { 
     return "drop sequence " + sequenceName; 
    } 

    @Override 
    public String getQuerySequencesString() { 
     return "select relname from pg_class where relkind='S'"; 
    } 

} 

public void printSequenceName (SequenceQueryGenerator queryGenerator, Connection conn) throws SQLException { 
     String sql = queryGenerator.getQuerySequencesString(); 
     if (sql!=null) { 

      Statement statement = null; 
      ResultSet rs = null; 
      try { 
       statement = conn.createStatement(); 
       rs = statement.executeQuery(sql); 

       while (rs.next()) { 
        System.out.println("Sequence Name : " + rs.getString(1)); 
       } 
      } 
      finally { 
       if (rs!=null) rs.close(); 
       if (statement!=null) statement.close(); 
      } 

     } 
    } 

public static void main(String[] args) { 
     Connection jdbcConnection = null; 
     try { 
      jdbcConnection = DriverManager.getConnection("", "", ""); 
      printAllSequenceName(new OracleSequenceQueryGenerator(), jdbcConnection); 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }finally { 
      if(jdbcConnection != null) { 
       try { 
        jdbcConnection.close(); 
       } catch (SQLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
} 
0

鑑於最近的Oracle JDBC驅動程序(如12.1.0.2)的版本don't return sequence information當你調用DatabaseMetaData#getTablestypes設置爲["SEQUENCE"],最好的辦法是運行必要的查詢自己,如:

SELECT o.owner AS sequence_owner, 
     o.object_name AS sequence_name 
    FROM all_objects o 
    WHERE o.owner LIKE 'someOwnerPattern' ESCAPE '/' 
    AND o.object_name LIKE 'someNamePattern' ESCAPE '/' 
    AND o.object_type = 'SEQUENCE' 
    ORDER BY 1, 2 

...其中someOwnerPatternsomeNamePattern就像你與使用的那些SQL模式運營商(例如%匹配任何內容)。

這與驅動程序本身運行的查詢基本相同,只是它查詢SEQUENCE類型的對象。