如何从JDBC检索序列元数据?

我试图从Java代码(使用基本JDBC)检索我的Oracle DB的不同类型的元数据。 例如,如果我想检索带有_FOO后缀的表列表,我可以执行以下操作:

 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等查询?

您无法通过JDBC API执行此操作,因为某些数据库(仍然)不支持序列。

获取它们的唯一方法是查询DBMS的系统目录(当你提到user_sequences我想你的Oracle就是这样)

有同样的问题。 这很容易。 只需将“SEQUENCE”传入getMetaData()。getTables()类型param即可。

在您的具体情况下,它将是这样的:

meta.getTables(connection.getCatalog(),null,“%_FOO”,new String [] {“SEQUENCE”});

您可以使用hibernate方言api来检索序列名称。 请参阅: http : //docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/dialect/Dialect.html

从下面的示例中,您可以看到如何使用dialect来获取序列名称

 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(); } } } } 

如果您不想使用hibernate,那么您必须创建自定义顺序特定实现。

自定义实现的示例代码

 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(); } } } } 

鉴于最近版本的Oracle JDBC驱动程序(例如12.1.0.2)在调用types设置为["SEQUENCE"] DatabaseMetaData#getTables时不返回序列信息 ,您最好的选择是自己运行必要的查询,例如:

  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模式,就像你用LIKE运算符一样(例如%匹配任何东西)。

这与驱动程序本身运行的查询基本相同,只是它查询SEQUENCE类型的对象。