1

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

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

USER_ID:编号、主键、自动编号

USER_NAME:VARCHAR2,唯一

密码: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

4

3 回答 3

2

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

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

...

该插入语句将向供应商表中插入一条新记录。供应商 ID 字段将被分配来自供应商序列的下一个数字。供应商名称字段将设置为卡夫食品。

你说:

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

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

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

是可以查看您的数据并USER_ID使用1.

如果现在由于主键 on 导致违反约束USER_ID,这可能意味着您已将数据插入到 users 表中,并且该数据包含USER_ID列的值。USER_ID例如,假设创建了 3 条记录并在不使用序列的情况下手动为其赋值

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');

然后,当您开始使用该序列(或仅在那时创建它)时,该序列将从 value = 指定的开头开始1。这样做

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

因为 sequence.nextval 将是 1,所以会产生约束冲突。

于 2012-09-28T07:17:28.730 回答
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 的最大值的最小值重新创建它。

分享和享受。

于 2012-09-28T11:50:47.307 回答
-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;
于 2013-09-27T08:40:31.053 回答