繁体   English   中英

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

[英]ORA-02289: sequence does not exist, cannot find my error

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

        }

}

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

当我尝试按顺序在表中插入一些数据时,它说该数据不存在,但我确实创建了它。 另外我不确定我是否需要prepareStatement.setInt(1,seq_id.nextval); 它给出了一个错误,但我不太确定我该怎么做

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

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

您正在准备一个带有一个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();

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

但是,如果确实需要这样做,则可以改进当前解决方案,以便考虑以下几点:

  • 仅当数据库中尚不存在对象时才执行CREATE语句。 这可以通过首先检查USER_OBJECTS数据字典视图来完成。
  • 使用普通Statement而不是PreparedStatement来执行DDL (预备语句仅对使用输入变量的DML操作有用)
  • 通过try-with-resources构造简洁安全地处理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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM