2016-06-26 9 views
1

PostgreSQLでは、ユーザがカスタム値を指定することができない自動インクリメントカラムを持つテーブルを作成します。シリアル列の次のシーケンスを常に使用する(ユーザ値は許可されていません)

Oracleでは、自動インクリメント列を作成する2つの方法があります。

この最初の例では、ユーザーが値を明示しない場合は、id列が自動的に増分されます。これはpostgresにおけるSERIALの現在の実装です。

CREATE TABLE identity_test_tab ( 
    id NUMBER GENERATED BY DEFAULT AS DENTITY, 
    description VARCHAR2(30) 
); 

次の例ではID列は、常に自動的にインクリメントし、ユーザが任意の値を指定することはできませんです。

CREATE TABLE identity_test_tab (
    id   NUMBER ALWAYS AS IDENTITY, 
    description VARCHAR2(30) 
); 

postgresの2番目の例と同等のことを知りたいですか?

+1

あなたがこれを行うためのトリガを必要とします。 –

+0

トリガーは、ユーザーによって定義された値にかかわらず、シーケンスからの値を「書き換え」ます。 btw - この動作は、値が受け入れられたというユーザの錯覚をもたらしますが、トリガはシーケンスからの値を消費します。 –

+0

@ VaoTsun:ユーザが値 –

答えて

2

それだけで特定の列のための助成金の挿入によって行うことができる

postgres=# insert into t(i,x,y) values(10,'x',1); 
ERROR: permission denied for relation t 
postgres=# insert into t(i,x,y) values(default,'x',1); 
ERROR: permission denied for relation t 
postgres=# insert into t(x,y) values('x',1); 
INSERT 0 1 
postgres=# select * from t; 
i | x | y 
---+---+--- 
1 | x | 1 
(1 row) 
+0

クール、それはトリガーなしで動作するとは思わなかった:) – Thomas

3

値が常にシーケンスから取得されるようにするには、トリガーが必要です。 Postgresの中generated alwaysに相当するものはありません。

create table foo (id integer not null primary key); 
create sequence foo_id_seq; 
alter sequence foo_id_seq owned by foo.id; -- this is essentially what `serial` does in the background 

create function generate_foo_id() 
    returns trigger 
as 
$$ 
begin 
    new.id := nextval('foo_id_seq'); 
    return new; 
end; 
$$ 
language plpgsql;  

create trigger foo_id_trigger 
    before insert on foo 
    for each row execute procedure generate_foo_id(); 

上記黙っシーケンス値を持つfoo.idのために任意のユーザ指定された値に置き換えられます。例外を上げる

create function generate_foo_id() 
    returns trigger 
as 
$$ 
begin 
    if new.id is not null then 
    raise 'No manual value for id allowed'; 
    end if; 
    new.id := nextval('foo_id_seq'); 
    return new; 
end; 
$$ 
language plpgsql; 

現在のトランザクションをアボートし、ロールバックする値を挿入するアプリケーションを強制し、それが正しく実行します。それを行うときに、明示的なエラーをしたい場合は、トリガ関数で例外が発生します。その後、

drop table if exists t; 
create table t(i serial, x text, y int); 
grant insert (x,y) on table t to abelisto; 
grant usage on sequence t_i_seq to abelisto; 
grant select on table t to abelisto; 

そして:

関連する問題