2014年半ばのOracleバージョン12cより前の、世界中のデータベース管理者の不満の多くは、Oracleには、テーブルスキーマ内に自動インクリメント列を本質的に生成する固有の機能がなかっただけです。この設計上の決定の理由は推測することしかできませんが、幸いなことに、古いOracleシステムのユーザーでも、この落とし穴を回避して、自動インクリメントされた独自の主キー列を作成するための回避策が考えられます。
最初のステップは、SEQUENCE
を作成することです データベース内。これは、複数のユーザーがアクセスして増分値を自動的に生成できるデータオブジェクトです。ドキュメントで説明されているように、Oracleのシーケンスは、各連続アイテムが生成される前に複数のユーザーが効果的に「交代」することを強制されるため、重複する値が同時に作成されるのを防ぎます。
新しいテーブルの一意の主キーを作成するには、最初にCREATE
を実行する必要があります。 使用するテーブル:
CREATE TABLE books (
id NUMBER(10) NOT NULL,
title VARCHAR2(100) NOT NULL
);
次に、PRIMARY KEY
を追加する必要があります 制約:
ALTER TABLE books
ADD (
CONSTRAINT books_pk PRIMARY KEY (id)
);
最後に、SEQUENCE
を作成します これは後で実際に一意の自動インクリメント値を生成するために使用されます。
CREATE SEQUENCE books_sequence;
テーブルを作成して準備ができている間、シーケンスはこれまでのところそこに座っているだけですが、使用されることはありません。ここでTRIGGERS
入ってください。
event
に似ています 最新のプログラミング言語では、TRIGGER
Oracleでは、特定のイベントが発生したときに実行されるストアドプロシージャです。
通常、TRIGGER
テーブルが更新されたとき、またはレコードが削除されたときに起動するように構成され、必要に応じて少しクリーンアップします。
この例では、TRIGGER
を実行します。 INSERT
の前 私たちのbooks
に テーブル、SEQUENCE
を確認します がインクリメントされ、その新しい値が主キー列に渡されます。
CREATE OR REPLACE TRIGGER books_on_insert
BEFORE INSERT ON books
FOR EACH ROW
BEGIN
SELECT books_sequence.nextval
INTO :new.id
FROM dual;
END;
ここでは、TRIGGER
を作成(または存在する場合は置換)しています。 名前付きbooks_on_insert
トリガーをBEFORE INSERT
で起動するように指定します books
に対して発生します テーブル、およびその中のすべての行に適用できます。
トリガー自体の「コード」は非常に単純です。SELECT
以前に作成したbooks_sequence
からの次の増分値 SEQUENCE
、それを:new
に挿入します books
の記録 指定された.id
のテーブル フィールド。
注:FROM dual
一部は適切なクエリを完了するために必要ですが、事実上無関係です。 dual
テーブルはデータの単一のダミー行であり、この場合は追加されます。これは無視できるようにするためであり、代わりに、ある種のデータを返すのではなく、トリガーのシステム関数を実行できます。
IDENTITY列
IDENTITY
列はOracle12cで導入され、最新バージョンのOracleで単純な自動インクリメント機能を使用できるようになりました。
IDENTITY
を使用する 列は、他のデータベースシステムの列と機能的に類似しています。上記のbooks
を再作成する 最新のOracle12c以降のテーブルスキーマでは、次の列定義を使用するだけです。
CREATE TABLE books (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
title VARCHAR2(100) NOT NULL
);