1

私はOracleとOracleApplicationExpressを初めて使用します。

マニュアルを使用していて、次の3つのフィールドを持つテーブルを作成しようとしています。

USER_ID:番号、主キー、自動番号

USER_NAME:VARCHAR2、一意

パスワード:VARCHAR2

APEX SQL Workshopウィザードを使用してテーブルを作成しましたが、次のようなことをしようとすると、次のようになります。

INSERT INTO Schema.USERS (USER_NAME,PASSWORD) VALUES ('planet','password');

...主キーの一意性制約に違反していると言われました。

トリガーは、テーブル作成ウィザードによって自動的に作成されました。次のようになります。

create or replace trigger "BI_USERS" 
  before insert on "USERS"               
  for each row  
begin   
  if :NEW."USER_ID" is null then
    select "USERS_SEQ".nextval into :NEW."USER_ID" from sys.dual;
  end if;
end; 

これにより、USERSのUSER_IDフィールドで最大の数値が自動的に検出され、新しいINSERTごとに増分値が自動的に割り当てられるという印象を受けましたが、これは発生していないようです。

誰かが私が間違っているかもしれないことを提案できますか?

どうもありがとう

pt

4

3 に答える 3

2

@Tomが言ったように、USER_IDの値を指定する行をテーブルに挿入した場合、シーケンスの使用はバイパスされ、シーケンスからフェッチされる値と重複するUSER_ID値を持つ行がテーブルに存在する可能性があります。したがって、新しい行を挿入すると、PRIMARY KEYCONSTRAINTVIOLATIONエラーが発生します。これを回避するには、次のように、シーケンスから値を「消費」してそれらを破棄する小さなスクリプトを記述します。

DECLARE
  n       NUMBER := 122;  -- or however many sequence values you need to consume
  seqVal  NUMBER;
BEGIN
  FOR i IN 1..n LOOP
    SELECT USERS_SEQ.NEXTVAL INTO seqVal FROM DUAL;
  END LOOP;
END;

もう1つの方法は、シーケンスを削除し、USERS.USER_IDの最大値よりも大きい最小値でシーケンスを再作成することです。

共有してお楽しみください。

于 2012-09-28T11:50:47.307 に答える
2

シーケンスhttp ://www.techonthenet.com/oracle/sequences.php

(リンクされた記事から引用)
Oracleでは、シーケンスを使用して自動番号フィールドを作成できます。シーケンスは、数列を生成するために使用されるOracleのオブジェクトです。これは、主キーとして機能する一意の番号を作成する必要がある場合に役立ちます。

..。

この挿入ステートメントは、suppliersテーブルに新しいレコードを挿入します。supply_idフィールドには、supplier_seqシーケンスの次の番号が割り当てられます。supply_nameフィールドはKraftFoodsに設定されます。

あなたが言った:

USER_IDこれにより、のフィールドで最大の数値が自動的に検出され、USERS新しいINSERTごとに増分値が自動的に割り当てられるという印象を受けましたが、これは発生していないようです。

いいえ。シーケンスは、最後の値と増分に基づいて次の値を生成するだけであり、データに関連付けられていません。

select nvl(max(user_id), 0) + 1 
  into v_next_val 
  from users 

あなたのデータを見て、で最も高くインクリメントするものUSER_IDです1

現在、の主キーが原因で制約違反が発生している場合はUSER_ID、usersテーブルにデータが挿入されており、このデータにUSER_ID列の値が含まれている可能性があります。たとえば、3つのレコードを作成USER_IDし、シーケンスを使用せずに手動で値を割り当てたとします。

insert into users (user_id, user_name) values (1, 'John');
insert into users (user_id, user_name) values (2, 'Jerry');
insert into users (user_id, user_name) values (3, 'Bob');

次にシーケンスの使用を開始すると(またはそのときのみ作成すると)、シーケンスは値=で指定された開始から開始されます1。そうすること

insert into users (user_name) values ('planet');

sequence.nextvalが1になるため、制約違反が生成されます。

于 2012-09-28T07:17:28.730 に答える
-1

これは役立つ場合があります。

create or replace TRIGGER  "TR_USER"
before insert on "USER"
for each row
begin   
   if :NEW."IDUSER" is null then
     select max("IDUSER")+1 into :NEW."IDUSER" from USER;
  end if;
end;
于 2013-09-27T08:40:31.053 に答える