我有一个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。
任何人都可以帮我修复这个错误吗?
感谢。
答案 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
。