46

特定のテーブルの最大値で始まるシーケンスをOracleで作成しようとしています。なぜこれが機能しないのですか?

CREATE SEQUENCE transaction_sequence
  MINVALUE 0
  START WITH (SELECT MAX(trans_seq_no)
     FROM TRANSACTION_LOG) 
  INCREMENT BY 1
  CACHE 20;
4

8 に答える 8

37

PL / SQLを使用できる場合は、試してみてください(編集:Neilのxlntの提案を組み込んで、次に高い値から開始します)。

SELECT 'CREATE SEQUENCE transaction_sequence MINVALUE 0 START WITH '||MAX(trans_seq_no)+1||' INCREMENT BY 1 CACHE 20'
  INTO v_sql
  FROM transaction_log;

EXECUTE IMMEDIATE v_sql;

考慮すべきもう1つのポイント:CACHEパラメーターを20に設定すると、データベースがダウンした場合にシーケンス内の最大19個の値が失われるリスクがあります。CACHEd値は、データベースの再起動時に失われます。シーケンスを頻繁にヒットする場合、またはギャップをそれほど気にしない場合を除いて、1に設定します。

最後に、CACHEとINCREMENTBYに指定した値がデフォルトです。それらを省略して、同じ結果を得ることができます。

于 2009-04-28T16:38:51.530 に答える
31

ここに、うまく機能する私の例があります。

declare
 ex number;
begin
  select MAX(MAX_FK_ID)  + 1 into ex from TABLE;
  If ex > 0 then
    begin
            execute immediate 'DROP SEQUENCE SQ_NAME';
      exception when others then
        null;
    end;
    execute immediate 'CREATE SEQUENCE SQ_NAME INCREMENT BY 1 START WITH ' || ex || ' NOCYCLE CACHE 20 NOORDER';
  end if;
end;
于 2013-05-29T09:30:21.130 に答える
20

あなたはから始めたいかもしれませんmax(trans_seq_no) + 1.

見る:

SQL> create table my_numbers(my_number number not null primary key);

Table created.

SQL> insert into my_numbers(select rownum from user_objects);

260 rows created.

SQL> select max(my_number) from my_numbers;

MAX(MY_NUMBER)
--------------
           260

SQL> create sequence my_number_sn start with 260;

Sequence created.

SQL> insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);
insert into my_numbers(my_number) values (my_number_sn.NEXTVAL)
*
ERROR at line 1:
ORA-00001: unique constraint (NEIL.SYS_C00102439) violated

数値を使用してシーケンスを作成する場合、シーケンスに対して最初に選択したときに、Oracleは割り当てた初期値を返すことを覚えておく必要があります。

SQL> drop sequence my_number_sn;

Sequence dropped.

SQL> create sequence my_number_sn start with 261;

Sequence created.

SQL>  insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);

1 row created.

あなたが「ギャップのない」ことをしようとしているなら、私はあなたに強くお勧めします

1はそれを行わず、#2はそのためのシーケンスを使用しません。

于 2009-04-28T17:04:00.490 に答える
19

CREATE SEQUENCEステートメント内で副選択を使用することはできません。事前に値を選択する必要があります。

于 2009-04-28T16:26:01.437 に答える
12

途中で、MAX値はコミットされた値の最大値になります。1234が返される可能性があり、誰かがすでに1235を挿入しているが、コミットされていないことを考慮する必要がある場合があります。

于 2009-04-28T23:14:21.190 に答える
7

Ivan Laharnarに基づいており、コードが少なく、シンプルです。

declare
    lastSeq number;
begin
    SELECT MAX(ID) + 1 INTO lastSeq FROM <TABLE_NAME>;
    if lastSeq IS NULL then lastSeq := 1; end if;
    execute immediate 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || lastSeq || ' MAXVALUE 999999999 MINVALUE 1 NOCACHE';
end;
于 2017-07-13T19:20:37.430 に答える
2
DECLARE
    v_max NUMBER;
BEGIN
    SELECT (NVL (MAX (<COLUMN_NAME>), 0) + 1) INTO v_max FROM <TABLE_NAME>;
    EXECUTE IMMEDIATE 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || v_max || ' NOCYCLE CACHE 20 NOORDER';
END;
于 2017-11-17T07:38:52.923 に答える
0

動的SQLを使用する

BEGIN
            DECLARE
            maxId NUMBER;
              BEGIN
              SELECT MAX(id)+1
              INTO maxId
              FROM table_name;          
              execute immediate('CREATE SEQUENCE sequane_name MINVALUE '||maxId||' START WITH '||maxId||' INCREMENT BY 1 NOCACHE NOCYCLE');
              END;
END;
于 2019-09-19T11:37:16.837 に答える