web-dev-qa-db-ja.com

トリガーを使用せずにOracleで自動インクリメント

トリガーの使用以外に、Oracleで自動インクリメントを実現する他の方法は何ですか?

22
Lakshmi

Oracleの時代から思い出す限り、TRIGGERを使用せずに自動インクリメント列を作成することはできません。自動インクリメント列を作成するための解決策には、TRIGGERとSEQUENCEが含まれます(これはすでに知っていると思いますので、トリガーのコメントはありません)。

3
Salamander2007

Oracleシーケンスを作成して使用できます。構文と詳細は http://www.techonthenet.com/Oracle/sequences.php にあります。

他のRDBMSのAUTONUMBERに関する制限を理解するには、記事 http://rnyb2.blogspot.com/2006/02/potential-pitfall-with-Oracle-sequence.html もお読みください。

18
Dheer

連番は必要なく、一意のIDのみが必要な場合は、SYS_GUID()のDEFAULTを使用できます。すなわち:

CREATE TABLE xxx ( ID RAW(16) DEFAULT SYS_GUID() )
16
angus

シーケンスから次の値を取得するトリガーは、AUTOINCREMENTと同等の機能を実現するための最も一般的な方法です。

create trigger mytable_trg
before insert on mytable
for each row
when (new.id is null)
begin
    select myseq.nextval into :new.id from dual;
end;

挿入を制御する場合はトリガーは必要ありません。挿入ステートメントでシーケンスを使用するだけです。

insert into mytable (id, data) values (myseq.nextval, 'x');

これはAPIパッケージ内に隠すことができるため、呼び出し元はシーケンスを参照する必要がありません。

mytable_pkg.insert_row (p_data => 'x');

ただし、トリガーの使用はより「透過的」です。

11
Tony Andrews

12cから、 identity column を使用できます。これにより、テーブルと自動インクリメントの間のリンクが明示的になります。トリガーやシーケンスは必要ありません。構文は次のようになります。

create table <table_name> ( <column_name> generated as identity );
2
Ben

シーケンスを作成します。

create sequence seq;

次に、値を追加します

insert into table (id, other1, other2)
values (seq.nextval, 'hello', 'world');

注:シーケンスに関するその他のオプション(開始値、増分など)については、Oracleのドキュメントを参照してください。

2
FerranB

「トリガーベース」のソリューションを実際に使用したくない場合は、プログラムによるアプローチで自動インクリメント機能を実現し、getGeneratedKeys()メソッドで自動インクリメントキーの値を取得できます。

検討のためのコードスニペットは次のとおりです。

Statement stmt = null;
ResultSet rs = null;

stmt = conn.createStatement(Java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                Java.sql.ResultSet.CONCUR_UPDATABLE);

stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTable");

stmt.executeUpdate("CREATE TABLE autoIncTable ("
                + "priKey INT NOT NULL AUTO_INCREMENT, "
                + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

stmt.executeUpdate("INSERT INTO autoIncTable  (dataField) "
                + "values ('data field value')",
                Statement.RETURN_GENERATED_KEYS);

int autoIncKeyFromApi = -1;

rs = stmt.getGeneratedKeys();

if (rs.next()) {
    autoIncKeyFromApi = rs.getInt(1);
}
else {
    // do stuff here        
}

rs.close();

ソース: http://forums.Oracle.com/forums/thread.jspa?messageID=3368856

0
XpiritO

たとえばに加えてFerranBの答え:
MySQLでauto_incementがどのように機能するかとは対照的に、おそらく言及する価値があります。

  • シーケンスはデータベース全体で機能するため、複数のテーブルに使用でき、値はデータベース全体で一意です
    • したがって、テーブルを切り捨てても、「自動インクリメント」機能はリセットされません。
  • 0
    Reinier