Oracle APEX,自动编号不起作用?

Oracle APEX,自动编号不起作用?,oracle,plsql,sequence,oracle-apex,Oracle,Plsql,Sequence,Oracle Apex,我不熟悉Oracle,也不熟悉Oracle Application Express 我正在阅读一本手册,并试图创建一个包含3个字段的表: 用户ID:编号、主键、自动编号 用户名:VARCHAR2,唯一 密码:VARCHAR2 我使用APEX SQL Workshop向导创建表,但当我尝试执行以下操作时: INSERT INTO Schema.USERS (USER_NAME,PASSWORD) VALUES ('planet','password'); DECLARE n NU

我不熟悉Oracle,也不熟悉Oracle Application Express

我正在阅读一本手册,并试图创建一个包含3个字段的表:

用户ID:编号、主键、自动编号

用户名:VARCHAR2,唯一

密码:VARCHAR2

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

INSERT INTO Schema.USERS (USER_NAME,PASSWORD) VALUES ('planet','password');
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;
…我被告知违反了主键上的唯一约束

触发器由表创建向导自动创建。看起来是这样的:

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; 
我的印象是,这将自动在用户的USER_ID字段中找到最高的数值,并自动为每个新插入指定递增的值,但这似乎没有发生

有人能告诉我可能做错了什么吗

非常感谢


pt序列

序列

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

此insert语句将在供应商中插入新记录 桌子供应商id字段将从中分配下一个编号 供应商的顺序如下。供应商名称字段将设置为 卡夫食品

你说:

我觉得这会自动找到最高的
USERS
USER\u ID
字段中的数值,并自动 为每个新插入指定一个递增的值,但这不会 似乎正在发生

不会。序列只会基于最后一个值和增量生成下一个值,并且与数据无关

select nvl(max(user_id), 0) + 1 
  into v_next_val 
  from users 
查看您的数据并使用
1
增加最高的
用户ID

如果您现在由于
USER\u ID
上的主键而受到约束冲突,这可能意味着您已将数据插入到用户表中,并且该数据包含
USER\u ID
列的值。 例如,假设创建了3条记录并手动为
USER\u 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

正如@Tom所说,如果您在表中插入了为USER_ID指定值的行,那么序列的使用将被忽略,现在表中可能有具有USER_ID值的行,这些值与从序列中获取的值重复;因此,在插入新行时,会出现主键约束冲突错误。要解决此问题,请编写一个小脚本,该脚本“使用”序列中的值并将其丢弃,如下所示:

INSERT INTO Schema.USERS (USER_NAME,PASSWORD) VALUES ('planet','password');
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最大值的最小值重新创建它

分享和享受。

这会很有帮助:

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;

或者,正如techonthenet文章所描述的:将increment设置为121,执行一个nextval,然后将increment重置为1。另外,如果你重新创建序列,我不一定会触及最小值,而是以值开头。谢谢鲍勃,希望我能标记多个帖子作为答案——我甚至还没有达到向上投票帖子的阈值。然而,我仍然感谢你的意见!谢谢你的回答!ptNever-ever-user max(id)+1用于填充序列。这将在多用户环境中失败。