2012-12-10 34 views
1

我有一個Oracle數據庫表:oracle - 如何使用序列作爲自動增量ID?

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應用程序插入記錄,狗ID將與1日開始,而不是21 。

任何人都可以幫助我解決這個錯誤?

謝謝。

+0

在你的C#代碼然後你通過「Id」列?我想你一定是。如果ID沒有被傳入,觸發器被編碼爲只觸發(when子句)。另外,我建議你不要在DB對象中使用帶引號的名稱。 – DazzaL

+0

我不確定我是否按照這個問題。在創建觸發器之前是否插入前20行?您是否通過明確指定「Id」值來插入前20行,從而防止觸發器被觸發?您的C#應用​​程序是否傳遞了導致觸發器被繞過的「Id」值(即明確傳遞值1)? –

+0

具有id值的前20行。在我的C#代碼中沒有「Id」列。 – Rock

回答

6

序列不是「自動增量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描述使用觸發器和序列的行爲。

而且IDENTITY列現在可以在Oracle 12c中

+0

所以這是一個oracle的錯誤? :-) – Rock

+7

如果無法閱讀你的思想是一個錯誤。好的。 –

+0

這聽起來像是你說你不能使用序列和觸發器來使插入行爲像自動遞增列一樣。看起來並非如此,例如[這個答案](http://stackoverflow.com/a/11296469/498594)。 – Kelvin

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; 
-1

我覺得你用錯了Seq name

而不是使用DOGINFO_SEQ使用USERINFO_SEQ