oracle - 如何使用序列作为自动增量id?

时间:2012-12-10 10:23:26

标签: oracle

我有一个oracle数据库表:

CREATE TABLE "DogInfo" (
"Id" NUMBER NOT NULL ENABLE,
"DogName" VARCHAR2 (50 CHAR) NOT NULL ENABLE,
"DogAge" NUMBER NOT NULL ENABLE,
CONSTRAINT "DogInfo_PK" PRIMARY KEY ("Id") ENABLE
);

CREATE SEQUENCE "DOGINFO_SEQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE;

CREATE OR REPLACE TRIGGER  "BI_DogInfo" 
BEFORE INSERT ON "DogInfo" FOR EACH ROW
WHEN (NEW."Id" IS NULL OR NEW."Id" = 0) BEGIN
    SELECT "USERINFO_SEQ".nextval INTO :NEW."Id" FROM dual;
END;

ALTER TRIGGER  "BI_DogInfo" ENABLE;

如果我使用数据库工具在表中插入20条记录,然后使用我的C#Web应用程序插入记录,那么dog id将从1开始,而不是21。

任何人都可以帮我修复这个错误吗?

感谢。

3 个答案:

答案 0 :(得分:7)

序列不是“自动增量ID”。

序列只是一个连续的唯一数字生成器。它可以作为您的Id列值提供程序,但它可以在列中保留正确的值。

我假设您添加了20行,如下所示:

insert into table(id, <columns>) values (1, <values>);
insert into table(id, <columns>) values (2, <values>);
and so on ...

你的序列无法知道你所期望的下一个数字是什么(当然除非你(重新)用所需的初始值创建它)。 相反,您应该始终使用序列中的值,如下所示:

insert into table(id, <columns>) values (sequence.nextval, <values>);
insert into table(id, <columns>) values (sequence.nextval, <values>);
and so on ...

这样您就可以使序列与表ID值保持同步。

编辑:

您可以使用this answer中描述的触发器和序列来模仿该行为。

现在,Oracle 12c上也提供了IDENTITY列

答案 1 :(得分:0)

如果您想以20而不是1开始,则需要更改序列。

CREATE SEQUENCE "DOGINFO_SEQ" MINVALUE 20 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 20 CACHE 20 NOORDER NOCYCLE;

似乎你没有在触发器中使用正确的序列。

CREATE OR REPLACE TRIGGER  "BI_DogInfo" 
BEFORE INSERT ON "DogInfo" FOR EACH ROW
WHEN (NEW."Id" IS NULL OR NEW."Id" = 0) BEGIN
SELECT "DOGINFO_SEQ".nextval INTO :NEW."Id" FROM dual;
END;

答案 2 :(得分:-1)

我认为您使用了错误的Seq name

而不是使用DOGINFO_SEQ使用USERINFO_SEQ