2

私は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 アプリケーションを使用してレコードを挿入すると、犬の ID は 21 ではなく 1 で始まります。

このバグの修正を手伝ってくれる人はいますか?

ありがとう。

4

3 に答える 3

7

シーケンスは「自動インクリメント ID」ではありません。

Sequence は、一連の一意の番号ジェネレーターです。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 値と同期させます。

編集 :

この回答で説明されているように、トリガーとシーケンスを使用してその動作を模倣できます。

また、IDENTITY 列が Oracle 12c で利用可能になりました

于 2012-12-10T10:38:29.207 に答える
0

1 ではなく 20 で開始する場合は、シーケンスを変更する必要があります。

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;
于 2014-09-16T09:14:52.610 に答える
-1

使い方が間違っていると思いますSeq name

DOGINFO_SEQuseを使用する代わりにUSERINFO_SEQ.

于 2015-02-18T06:45:50.297 に答える