如何将序列当前值更改为以前的值?

How to Change Sequence current value to the previous value?

在我的项目中,我有一个交易功能。如果该交易失败,则所有数据都将恢复到前一阶段。

考虑一下,在该事务中,我使用序列的下一个值将值插入 table。如果交易失败,那么我想重置或更改序列到以前的值。

如果可以,请举个例子。

我测试了,但是我得到了错误:

java.sql.SQLException: ORA-08002: sequence TEST.CURRVAL is not yet defined in this session

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1017)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:655)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:249)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:566)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:215)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:776)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:897)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1034)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3820)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3867)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1502)

这是我的代码:

        String sql1 = "select test.currval from dual";
        pst = conn.prepareStatement(sql1);
        rs = pst.executeQuery();
        int currentValue = 0;
        if(rs.next()){
            currentValue = rs.getInt(1);
        }
        currentValue -= 1;
        String sql2 = "alter sequence Test start with '"+currentValue+"'";
        pst = conn.prepareStatement(sql2);
        pst.execute();
        pst = conn.prepareStatement(sql1);
        rs = pst.executeQuery();
        if(rs.next()){
            JOptionPane.showMessageDialog(null, rs.getInt(1),"Current Sequence Number",JOptionPane.INFORMATION_MESSAGE); ;
        }

ORA-08002 表示您已尝试在调用序列下一个值之前获取序列当前值。这在 Oracle 中是非法的。

SELECT test.CURRVAL
FROM dual; -->illegal

SELECT test.NEXTVAL
FROM dual;
SELECT test.CURRVAL
FROM dual; -->legal

请阅读此post以获得更好的理解。

我会试着告诉你为什么不应该这样做而不是怎么做。

你试图达到的目的违背了顺序的目的。序列是为了给你一个唯一的标识符,如果你跳过一些值也没关系。总有一天,尝试回滚到旧值,尤其是在您有并发事务的情况下(您今天可能没有,但您可能会在某个时候有意或无意地进行多次调用)会给您带来严重的问题。

所以我建议不要这样做。

请注意,更改序列号以手动解决问题与将其作为流程的一部分进行操作是不同的,我想说的是不要将其作为代码流程的一部分进行操作。

尽管如此,搜索还是让我得到了这个答案。推荐阅读。