0

編集あなたのアドバイスの後、コードとエラー。「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)
4

1 に答える 1

1

createDB()SQL ステートメントのいずれかでエラーが発生した場合 (たとえば、テーブルが存在せず、それを削除しようとした場合)、メソッドに問題が発生します。その時点で、コードはcatchブロックにジャンプし、データベース オブジェクトは作成されません。各 DROP ステートメントを try/catch ブロックでラップして、エラーをキャッチして処理できるようにする必要があります (または、おそらく無視しても安全です)。その後、CREATEステートメントが実行されます。

DROPまた、テーブルのステートメントのみを実行しています。シーケンスとトリガーについても同じことを行う必要があります。

あなたのトリガーも無効です。accounts テーブルには、 および の列のみがありaccount_idますbalance。操作テーブルの列の値を参照:oldすることはできません。とは無効で、は accounts テーブルの:newaccount_idです (これは外部キーであるため、テーブルの と同じであることがわかります)。また、2 つのセミコロンがありません。次のようになります。:old.amount:new.amount:old.account_idaccount_idoperations

statmnt.executeUpdate("CREATE TRIGGER addingOrder BEFORE UPDATE ON accounts FOR EACH ROW BEGIN"
                    + " INSERT INTO operations(... columns ...) "
                    + " VALUES (... values ...); END;");

物事をコーディングする方法では、最初にDROPPINGすべてでクリーンアップを実行し、次にすべてを実行しようとしていCREATEます。テストが完了すると、すべてのデータベース オブジェクトが配置されたままになります。テストの開始時にオブジェクトを作成するように順序を逆にすることをお勧めします。次にDROP、データベースがクリーンなままになるように、最後にすべてを破棄します。

于 2015-05-22T14:35:45.197 に答える