【问题标题】:ORA-02289: sequence does not exist, cannot find my errorORA-02289: 序列不存在,找不到我的错误
【发布时间】:2016-06-01 10:21:25
【问题描述】:
public static void main(String[] argv) {

    try {

        createTable();
        insertRecordIntoTable("leo","123");

    } catch (SQLException e) {

        System.out.println(e.getMessage());

    }

}

private static void createTable() throws SQLException {

    Connection dbConnection = null;
    PreparedStatement preparedStatement = null;
    String sequence = "CREATE SEQUENCE ID_SEQ INCREMENT BY 1 MAXVALUE 99999999999999999999 MINVALUE 1 CACHE 20";
    String createTableSQL = "CREATE TABLE DBUSER1("
            + "USER_ID NUMBER(5) NOT NULL, "
            + "USERNAME VARCHAR(20) NOT NULL, "
            + "PASSWORD VARCHAR(20) NOT NULL, "
            + "PRIMARY KEY (USER_ID) "
            + ")";

    try {
        dbConnection = getDBConnection();
        preparedStatement = dbConnection.prepareStatement(createTableSQL);

        System.out.println(createTableSQL);

        // execute create SQL stetement
        preparedStatement.executeUpdate(createTableSQL);
        preparedStatement.executeUpdate(sequence);




        System.out.println("Table \"dbuser\" is created!");

    } catch (SQLException e) {

        System.out.println(e.getMessage());

    } finally {

        if (preparedStatement != null) {
            preparedStatement.close();
        }

        if (dbConnection != null) {
            dbConnection.close();
        }

    }

}

private static Connection getDBConnection() {

    Connection dbConnection = null;

    try {

        Class.forName(DB_DRIVER);

    } catch (ClassNotFoundException e) {

        System.out.println(e.getMessage());

    }

    try {

        dbConnection = DriverManager.getConnection(
                        DB_CONNECTION, DB_USER,DB_PASSWORD);
        return dbConnection;

    } catch (SQLException e) {

        System.out.println(e.getMessage());

    }

    return dbConnection;

}

private static void insertRecordIntoTable(String username, String password) throws SQLException {


        Connection dbConnection = null;
        PreparedStatement preparedStatement = null;

        String insertTableSQL = "INSERT INTO DBUSER1"
                + "(USER_ID, USERNAME, PASSWORD) VALUES"
                + "(ID_SEQ.NEXTVAL,?,?)";

        try {
            dbConnection = getDBConnection();
            preparedStatement = dbConnection.prepareStatement(insertTableSQL);

            // execute insert SQL stetement

            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);
            preparedStatement.executeUpdate();

            System.out.println("Record is inserted into DBUSER table!");

        } catch (SQLException e) {

            System.out.println(e.getMessage());

        } finally {

            if (preparedStatement != null) {
                preparedStatement.close();
            }

            if (dbConnection != null) {
                dbConnection.close();
            }

        }

}

当我尝试为我的表创建序列时找不到错误。

当我尝试使用序列在我的表中插入一些数据时,它说它不存在,但我确实创建了它。另外我不确定是否需要preparedStatement.setInt(1, seq_id.nextval);它给出了一个错误,但我不太确定我会如何做到这一点

【问题讨论】:

  • 运行程序并查看 - 例如 - SQL Developer,序列和/或表是否存在?
  • 表存在但序列不存在
  • ORA-00955:名称已被现有对象使用 ORA-02289:序列不存在

标签: java sql jdbc


【解决方案1】:

解决方案可能是在序列名称之前添加架构名称(所有者):

  CREATE SEQUENCE some_nameOf_schema.ID_SEQ INCREMENT BY 1 MAXVALUE 99999999999999999999 MINVALUE 1 CACHE 20

【讨论】:

  • 我把它改成了这个 String SEQUENCE = "CREATE SEQUENCE ID_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NO CYCLE";
  • 我仍然收到错误 ORA-02289:序列不存在
【解决方案2】:

您正在使用一个 SQL 文本准备一个语句,并使用两个不同的 SQL 文本执行该语句;

preparedStatement = dbConnection.prepareStatement(createTableSQL);

preparedStatement.executeUpdate(createTableSQL);
preparedStatement.executeUpdate(sequence);

...根据文档实际上是无效的;

int executeUpdate(String sql) 抛出 SQLException
执行给定的 SQL 语句,可能是 INSERT、UPDATE 或 DELETE 语句或不返回任何内容的 SQL 语句,例如 SQL DDL 语句。
注意:此方法不能在PreparedStatement 或 CallableStatement。

你需要做的是准备和执行两条不同的语句;

preparedStatement = dbConnection.prepareStatement(createTableSQL);
preparedStatement.executeUpdate();

preparedStatement = dbConnection.prepareStatement(sequence);
preparedStatement.executeUpdate();

【讨论】:

    【解决方案3】:

    一般来说,每次应用程序启动时CREATE 数据库对象没有多大意义,因为这通常只执行一次,当您安装/升级应用程序使用的数据库/架构时。

    但是,如果您真的必须这样做,可以改进当前的解决方案,以便考虑以下几点:

    • 仅当对象在 DB 中不存在时才执行 CREATE 语句。这可以通过首先检查USER_OBJECTS data dictionary view 来完成。
    • 使用普通的Statement 而不是PreparedStatement 来执行DDL(准备好的语句仅对使用输入变量的DML 操作有用)
    • 通过try-with-resources construct简洁安全地处理JDBC资源(Connection/Statement/ResultSet

    代码如下所示:

    // query constants
    private static final String CHECK_DB_OBJECT = 
                "SELECT 1 FROM user_objects WHERE object_name = ?";
    
    private static final String CREATE_SEQUENCE = 
            "CREATE SEQUENCE ID_SEQ INCREMENT BY 1 MAXVALUE 99999999999999999999" +
            " MINVALUE 1 CACHE 20";
    
    private static final String CREATE_TABLE = "CREATE TABLE DBUSER1("
            + "USER_ID NUMBER(5) NOT NULL, "
            + "USERNAME VARCHAR(20) NOT NULL, "
            + "PASSWORD VARCHAR(20) NOT NULL, "
            + "PRIMARY KEY (USER_ID) "
            + ")";
    
    /* clip the main method etc. */    
    
    /**
    * Creates the table and sequence only if they do not already exist.
    */
    private static void createTableAndSequenceIfAbsent() {
    
        try (Connection dbConnection = DriverManager.getConnection(
                DB_CONNECTION, DB_USER, DB_PASSWORD);
             PreparedStatement ps = dbConnection
                        .prepareStatement(CHECK_DB_OBJECT)) {
    
            if (!dbObjectExists(ps, "ID_SEQ")) {
                executeDDL(dbConnection, CREATE_SEQUENCE);
            }            
            if (!dbObjectExists(ps, "DBUSER1")) {
                executeDDL(dbConnection, CREATE_TABLE);
            }
    
        } catch (SQLException e) {
            e.printStackTrace();
        }    
    }
    
    private static boolean dbObjectExists(PreparedStatement ps,
            String objectName) throws SQLException {
    
        ps.setString(1, objectName);
        ResultSet rs = ps.executeQuery();
    
        // if the #CHECK_DB_OBJECT query returned a row, the object exists
        return rs.next();
    }
    
    private static void executeDDL(Connection c, String sql)
            throws SQLException {
    
        try (Statement st = c.createStatement()) {
            st.execute(sql);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      • 2021-09-19
      • 2021-09-03
      • 1970-01-01
      • 2021-08-01
      • 2015-07-22
      • 2014-08-31
      相关资源
      最近更新 更多