我是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
答案 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;