ORA-02289:序列不存在,找不到我的错误

时间:2016-02-19 18:19:20

标签: java sql jdbc

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);它给出了一个错误,但我不太确定我会怎么做

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

您正准备一个包含一个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();

答案 2 :(得分:0)

通常,每次应用程序启动时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);
    }
}