![](/img/trans.png)
[英]exception sequence.nextval maxvalue? (oracle sql)
[英]Decrement oracle sequence when an exception occurred
我嘗試使用 pl/sql 在我的數據庫中插入一條新記錄,所以首先我生成一個新序列,如下所示:
select my_seq.nextval into seqId from dual;
然后我嘗試使用生成的 seqId 插入一條新記錄,如下所示:
insert into myTable (id) values seqId ;
但是當插入過程中發生錯誤時,我想在異常塊中減少我的序列。 請問有人有想法嗎?
您不能在序列遞增后遞減(一個序列要么遞增要么遞減,而不是兩者)或重新初始化 Oracle 中的序列(從...開始)。 沒有辦法做到這一點。 希望這可以幫助。
但是,如果你想繼續這種荒謬的做法,你可以試試這個,但你需要先初始化你的序列,即 myseq.nextval; 那么您可以首先嘗試插入 currval ,如果成功,那么您可以增加您的序列,否則序列將具有其先前的值。
Declare
currval pls_integer;
inc pls_integer;
Begin
select seq.currval into currval from dual;
insert into myTable (id) values (currval) ;
select seq.nextval into inc from dual;
Exception
when others then
do the exception handling;
end;
正如你已經被告知的那樣,你根本不應該這樣做。 無論如何,這就是你可以做到的方式。
示例表和序列:
SQL> create table mytable (id number primary key);
Table created.
SQL> create sequence seq;
Sequence created.
SQL> set serveroutput on
將seq.nextval
插入mytable
並在發生故障時遞減序列的過程。 我正在以最簡單的方式進行操作 - 將其刪除並重新創建,並將start
參數設置為最后獲取的值 - 1 。 DBMS_OUTPUT
調用在這里只是為了顯示過程中發生了什么。
SQL> create or replace procedure p_test as
2 seqid number;
3 begin
4 seqid := seq.nextval;
5 dbms_output.put_line('Sequence number to be inserted = ' || seqid);
6
7 insert into mytable(id) values (seqid);
8
9 exception
10 when others then
11 dbms_output.put_line(sqlerrm);
12 execute immediate 'drop sequence seq';
13 execute immediate 'create sequence seq start with ' || to_char(seqid - 1);
14 end;
15 /
Procedure created.
讓我們測試一下:這應該插入1
:
SQL> exec p_test;
Sequence number to be inserted = 1
PL/SQL procedure successfully completed.
SQL> select * from mytable;
ID
----------
1
到目前為止,一切都很好。 現在,我將手動插入ID = 2
,以便下一個過程調用違反唯一約束:
SQL> insert into mytable values (2);
1 row created.
再次調用該過程:
SQL> exec p_test;
Sequence number to be inserted = 2
ORA-00001: unique constraint (SCOTT.SYS_C007547) violated
PL/SQL procedure successfully completed.
好的; 程序默默地完成。 它沒有插入任何東西,但它減少了序列:
SQL> select * from mytable;
ID
----------
1 --> populated with the first P_TEST call
2 --> populated manually
SQL> select seq.nextval from dual;
NEXTVAL
----------
1 --> sequence is decremented from 2 to 1
如果我刪除有問題的ID = 2
並重試:
SQL> delete from mytable where id = 2;
1 row deleted.
SQL> exec p_test;
Sequence number to be inserted = 2
PL/SQL procedure successfully completed.
SQL> select * from mytable;
ID
----------
1
2
SQL> select seq.nextval from dual;
NEXTVAL
----------
3
SQL>
正確的; 種作品,但它不值得痛苦。
此外,正如您所說,一個表中有 20 行。 如果有人刪除了第 13 行,你會怎么做。 你會遞減 #14 到 20 之間的所有值嗎? 如果那是一些外鍵引用的主鍵怎么辦?
說真的,不要這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.