Oracle APEX,autonumber不工作?

时间:2012-09-28 05:48:32

标签: oracle plsql sequence oracle-apex

我是Oracle的新手,也是Oracle Application Express的新手。

我正在编写手册,我正在尝试创建一个包含3个字段的表:

USER_ID:数字,主键,自动编号

USER_NAME:VARCHAR2,唯一

PASSWORD:VARCHAR2

我使用APEX SQL Workshop向导创建表,但是当我尝试执行以下操作时:

INSERT INTO Schema.USERS (USER_NAME,PASSWORD) VALUES ('planet','password');

...我被告知违反了主键的唯一约束。

表创建向导会自动创建一个触发器。它看起来像这样:

create or replace trigger "BI_USERS" 
  before insert on "USERS"               
  for each row  
begin   
  if :NEW."USER_ID" is null then
    select "USERS_SEQ".nextval into :NEW."USER_ID" from sys.dual;
  end if;
end; 

我认为这会自动在USERS的USER_ID字段中找到最高数值,并自动为每个新INSERT分配一个递增值,但这似乎不会发生。

任何人都可以提出我可能做错的建议吗?

非常感谢

PT

3 个答案:

答案 0 :(得分:2)

序列http://www.techonthenet.com/oracle/sequences.php

  

(引自链接文章)
  在Oracle中,您可以使用序列创建自动编号字段。一个   sequence是Oracle中用于生成数字的对象   序列。当您需要创建唯一编号时,这非常有用   充当主键。

     

...

     

此插入声明将向供应商插入新记录   表。将为supplier_id字段分配下一个号码   supplier_seq序列。 supplier_name字段将设置为   卡夫食品。

你说:

  

我的印象是这会自动找到最高的   USER_ID USERS字段中的数值并自动生成   为每个新INSERT分配一个递增的值,但事实并非如此   似乎正在发生。

没有。序列将根据最后一个值和增量生成下一个值,并且不依赖于您的数据。

select nvl(max(user_id), 0) + 1 
  into v_next_val 
  from users 

可以查看您的数据并使用USER_ID增加最高1

如果您现在因USER_ID上的主键而导致约束违规,这可能意味着您已将数据插入到用户表中,并且此数据包含USER_ID列的值。 例如,假设创建了3条记录并手动将值分配给USER_ID而不使用序列

insert into users (user_id, user_name) values (1, 'John');
insert into users (user_id, user_name) values (2, 'Jerry');
insert into users (user_id, user_name) values (3, 'Bob');

当您开始使用序列(或仅在此时创建它)时,序列将从指定的开始处开始,其值为1。 这样做

insert into users (user_name) values ('planet');

会生成约束违规,因为sequence.nextval将为1.

答案 1 :(得分:2)

正如@Tom所说,如果您在表中插入了为USER_ID指定值的行,则会绕过序列的使用,您现在可能在表中有USER_ID值的行,这些值将复制将从中获取的值序列;因此,在插入新行时,您将收到PRIMARY KEY CONSTRAINT VIOLATION错误。要解决这个问题,请编写一个小小的脚本,该序列“消耗”序列中的值并将其丢弃,如下所示:

DECLARE
  n       NUMBER := 122;  -- or however many sequence values you need to consume
  seqVal  NUMBER;
BEGIN
  FOR i IN 1..n LOOP
    SELECT USERS_SEQ.NEXTVAL INTO seqVal FROM DUAL;
  END LOOP;
END;

另一种方法是删除序列并使用大于USERS.USER_ID的最大值的最小值重新创建它。

分享并享受。

答案 2 :(得分:-1)

这可能会有所帮助:

create or replace TRIGGER  "TR_USER"
before insert on "USER"
for each row
begin   
   if :NEW."IDUSER" is null then
     select max("IDUSER")+1 into :NEW."IDUSER" from USER;
  end if;
end;