Oracle 序列创建了两次。 ORA-00955: 名称已被现有对象使用
Oracle sequence created twice. ORA-00955: name is already used by an existing object
编辑 在你的建议之后,代码和错误。我现在收到错误 "ORA-00955: name is already used by an existing object"。每次调用 DataStoreManager 构造函数时,序列创建都会产生此错误。
现在是代码:
public class DataStoreManager {
private Connection connection;
private PreparedStatement lookForAccount;
private PreparedStatement addAccount;
private PreparedStatement updaterBalance;
private PreparedStatement reachOperation;
public DataStoreManager(String url, String user, String password) throws DataStoreException, SQLException {
try {
connection = DriverManager.getConnection(url,user,password);
connection.setAutoCommit(false);
this.createDB();
lookForAccount = connection.prepareStatement("SELECT * FROM accounts WHERE account_id = ?");
addAccount = connection.prepareStatement("INSERT INTO accounts (account_id, balance) VALUES (? , 0.0)");
updaterBalance = connection.prepareStatement("UPDATE accounts SET balance = ? WHERE account_id = ?");
reachOperation = connection.prepareStatement("SELECT * FROM operations WHERE account_id = ? AND (date BETWEEN ? AND ?)");
} catch (SQLException error) {
error.printStackTrace();
throw error;
}
}
public void createDB() throws DataStoreException {
try {
Statement statmnt = connection.createStatement();
statmnt.executeUpdate("DROP TABLE operations");
statmnt.executeUpdate("DROP TABLE accounts");
statmnt.executeUpdate("CREATE TABLE accounts ( account_id INTEGER, balance DOUBLE PRECISION)");
statmnt.executeUpdate("CREATE TABLE operations ( operation_id INTEGER, account_id INTEGER, amount DOUBLE PRECISION, mydate DATE NOT NULL)");
//implement primary Key constraint.
statmnt.executeUpdate("ALTER TABLE accounts ADD CONSTRAINT accounts_PK PRIMARY KEY ( account_id )");
//implement foreign Key constraint
statmnt.executeUpdate("ALTER TABLE operations ADD CONSTRAINT accountID FOREIGN KEY ( account_id )"
+ "REFERENCES accounts ( account_id )");
// implement sequence for auto implement.
statmnt.executeUpdate("CREATE SEQUENCE operationID MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 10");
statmnt.executeUpdate("CREATE SEQUENCE logID MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 10");
// implement balance always positive constraint
statmnt.executeUpdate("ALTER TABLE accounts ADD CONSTRAINT balance_must_be_positive CHECK (balance >= 0)");
// Auto operation.
statmnt.executeUpdate("CREATE TRIGGER addingOrder BEFORE UPDATE ON accounts FOR EACH ROW BEGIN"
+ " INSERT INTO operations(operation_id, account_id, amount, mydate) "
+ " VALUES (operationID.nextval, :OLD.account_id, :NEW.amount - :OLD.amount, SYSDATE) END");
connection.commit();
} catch (Exception error) {
error.printStackTrace();
}
}
public boolean createAccount(int number) throws DataStoreException, SQLException {
try {
lookForAccount.setInt(1, number);
Boolean result = lookForAccount.execute();
if(result == true)
{
addAccount.setInt(1, number);
addAccount.executeUpdate();
connection.commit();
return true;
}
else
{ return false;}
} catch (SQLException error) {
error.printStackTrace();
throw error;
}
}
这是我的错误:
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:145)
Running single-user tests...
Running multi-users tests...
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
user#0[services.DataStoreManager@e00c09]: starting
user#0[services.DataStoreManager@e00c09]: exiting
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
user#1[services.DataStoreManager@111f9b]: starting
user#1[services.DataStoreManager@111f9b]: exiting
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)user#2[services.DataStoreManager@1363271]: starting
user#2[services.DataStoreManager@1363271]: exiting
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
user#3[services.DataStoreManager@114f313]: starting
user#3[services.DataStoreManager@114f313]: exiting
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)user#4[services.DataStoreManager@d767dc]: starting
user#4[services.DataStoreManager@d767dc]: exiting
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
如果您的任何 SQL 语句产生错误(例如,如果 table 不存在并且您尝试删除它)。届时,您的代码将跳转到 catch
块,并且将创建数据库对象的 none。您需要将每个 DROP 语句包装在 try/catch 块中,以便可以捕获和处理任何错误(或者在您的情况下,忽略它可能是安全的),然后 CREATE
语句将 运行 .
您的 table 也只是 运行ning DROP
陈述。您需要对序列和触发器执行相同的操作。
您的触发器也无效。帐户 table 只有 account_id
和 balance
的列。您不能为操作 table 中的列引用 :old
或 :new
值。所以 :old.amount
和 :new.amount
是无效的,:old.account_id
是帐户 table 中的 account_id(结果与 account_id
在 operations
table 中,因为它是外键)。您还缺少两个分号。它应该是这样的:
statmnt.executeUpdate("CREATE TRIGGER addingOrder BEFORE UPDATE ON accounts FOR EACH ROW BEGIN"
+ " INSERT INTO operations(... columns ...) "
+ " VALUES (... values ...); END;");
您对事物进行编码的方式是,您尝试先通过 DROPPING
一切进行清理,然后再 CREATE
一切。测试完成后,您将保留所有数据库对象。我建议您颠倒顺序,以便在测试开始时创建对象,然后在结束时拆除 DROP
一切,以便您的数据库保持干净。
编辑 在你的建议之后,代码和错误。我现在收到错误 "ORA-00955: name is already used by an existing object"。每次调用 DataStoreManager 构造函数时,序列创建都会产生此错误。
现在是代码:
public class DataStoreManager {
private Connection connection;
private PreparedStatement lookForAccount;
private PreparedStatement addAccount;
private PreparedStatement updaterBalance;
private PreparedStatement reachOperation;
public DataStoreManager(String url, String user, String password) throws DataStoreException, SQLException {
try {
connection = DriverManager.getConnection(url,user,password);
connection.setAutoCommit(false);
this.createDB();
lookForAccount = connection.prepareStatement("SELECT * FROM accounts WHERE account_id = ?");
addAccount = connection.prepareStatement("INSERT INTO accounts (account_id, balance) VALUES (? , 0.0)");
updaterBalance = connection.prepareStatement("UPDATE accounts SET balance = ? WHERE account_id = ?");
reachOperation = connection.prepareStatement("SELECT * FROM operations WHERE account_id = ? AND (date BETWEEN ? AND ?)");
} catch (SQLException error) {
error.printStackTrace();
throw error;
}
}
public void createDB() throws DataStoreException {
try {
Statement statmnt = connection.createStatement();
statmnt.executeUpdate("DROP TABLE operations");
statmnt.executeUpdate("DROP TABLE accounts");
statmnt.executeUpdate("CREATE TABLE accounts ( account_id INTEGER, balance DOUBLE PRECISION)");
statmnt.executeUpdate("CREATE TABLE operations ( operation_id INTEGER, account_id INTEGER, amount DOUBLE PRECISION, mydate DATE NOT NULL)");
//implement primary Key constraint.
statmnt.executeUpdate("ALTER TABLE accounts ADD CONSTRAINT accounts_PK PRIMARY KEY ( account_id )");
//implement foreign Key constraint
statmnt.executeUpdate("ALTER TABLE operations ADD CONSTRAINT accountID FOREIGN KEY ( account_id )"
+ "REFERENCES accounts ( account_id )");
// implement sequence for auto implement.
statmnt.executeUpdate("CREATE SEQUENCE operationID MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 10");
statmnt.executeUpdate("CREATE SEQUENCE logID MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 10");
// implement balance always positive constraint
statmnt.executeUpdate("ALTER TABLE accounts ADD CONSTRAINT balance_must_be_positive CHECK (balance >= 0)");
// Auto operation.
statmnt.executeUpdate("CREATE TRIGGER addingOrder BEFORE UPDATE ON accounts FOR EACH ROW BEGIN"
+ " INSERT INTO operations(operation_id, account_id, amount, mydate) "
+ " VALUES (operationID.nextval, :OLD.account_id, :NEW.amount - :OLD.amount, SYSDATE) END");
connection.commit();
} catch (Exception error) {
error.printStackTrace();
}
}
public boolean createAccount(int number) throws DataStoreException, SQLException {
try {
lookForAccount.setInt(1, number);
Boolean result = lookForAccount.execute();
if(result == true)
{
addAccount.setInt(1, number);
addAccount.executeUpdate();
connection.commit();
return true;
}
else
{ return false;}
} catch (SQLException error) {
error.printStackTrace();
throw error;
}
}
这是我的错误:
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:145)
Running single-user tests...
Running multi-users tests...
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
user#0[services.DataStoreManager@e00c09]: starting
user#0[services.DataStoreManager@e00c09]: exiting
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
user#1[services.DataStoreManager@111f9b]: starting
user#1[services.DataStoreManager@111f9b]: exiting
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)user#2[services.DataStoreManager@1363271]: starting
user#2[services.DataStoreManager@1363271]: exiting
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
user#3[services.DataStoreManager@114f313]: starting
user#3[services.DataStoreManager@114f313]: exiting
java.sql.SQLException: ORA-00955: name is already used by an existing object
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)user#4[services.DataStoreManager@d767dc]: starting
user#4[services.DataStoreManager@d767dc]: exiting
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:891)
at services.DataStoreManager.createDB(DataStoreManager.java:105)
at services.DataStoreManager.<init>(DataStoreManager.java:55)
at application.SimpleTest.main(SimpleTest.java:160)
如果您的任何 SQL 语句产生错误(例如,如果 table 不存在并且您尝试删除它)。届时,您的代码将跳转到 catch
块,并且将创建数据库对象的 none。您需要将每个 DROP 语句包装在 try/catch 块中,以便可以捕获和处理任何错误(或者在您的情况下,忽略它可能是安全的),然后 CREATE
语句将 运行 .
您的 table 也只是 运行ning DROP
陈述。您需要对序列和触发器执行相同的操作。
您的触发器也无效。帐户 table 只有 account_id
和 balance
的列。您不能为操作 table 中的列引用 :old
或 :new
值。所以 :old.amount
和 :new.amount
是无效的,:old.account_id
是帐户 table 中的 account_id(结果与 account_id
在 operations
table 中,因为它是外键)。您还缺少两个分号。它应该是这样的:
statmnt.executeUpdate("CREATE TRIGGER addingOrder BEFORE UPDATE ON accounts FOR EACH ROW BEGIN"
+ " INSERT INTO operations(... columns ...) "
+ " VALUES (... values ...); END;");
您对事物进行编码的方式是,您尝试先通过 DROPPING
一切进行清理,然后再 CREATE
一切。测试完成后,您将保留所有数据库对象。我建议您颠倒顺序,以便在测试开始时创建对象,然后在结束时拆除 DROP
一切,以便您的数据库保持干净。