2011-02-04 21 views
3

とテーブル内の列の最大値を選択し、私は、列の最大値を検索し、1をインクリメントし、それを使用する必要が行の値が挿入されています。テーブルに行を挿入する間、私は、Oracleデータベース</p> <p>を使用していない行

INSERT INTO dts_route 
    (ROUTE_ID, ROUTE_UID, ROUTE_FOLDER) 
VALUES (
         (SELECT MAX(ROUTE_ID) + 1 FROM route) , 
         ROUTE_UID, 
         ROUTE_FOLDER) 

テーブルに少なくとも1つのエントリがある場合、これはうまくいきます。 しかし、テーブルにエントリがない場合はnullを返します。

テーブルにエントリがない場合、どのようにしてデフォルト値1を得ることができますか。あなたのルートのID奇数のギャップ

答えて

10
SELECT COALESCE(MAX(ROUTE_ID),0) ... 
+9

@changed並行性のあるシステムで重複した値を取得する危険性があるこの方法を使用することを警告する必要があります。リスクは同時トランザクションの数に比例します。私はそれがあなたが避けようとしているものであるようにあなたに警告します。 – jachguate

1

自動インクリメントフィールドを作成します。 Oracleのシーケンスを使用して、この目標を達成することができます。

nullの場合、関数がnullを返す場合は、NVLを使用してデフォルト値(たとえば、0)を指定できます。

11

を気にしない場合のシーケンスを使用すると、これは安全な方法ではない方が簡単かもしれませんがNULLのデフォルト

SELECT NVL(MAX(ROUTE_ID),0) 

設定し

+7

+1と私は複数回投票できることを望みます。 MAX(key)+ 1はバグのある、非効率的なソリューションです。 –

2

使用を以下を参照してください。

INSERT INTO dts_route 
    (ROUTE_ID) 
SELECT COALESCE(MAX(r.route_id), 0) +1 
    FROM ROUTE r 

...しかし、あなたは本当にシーケンシャル数値で値を移入しsequenceを使用する必要があります。

CREATE SEQUENCE dts_route_seq; 

。 ..

INSERT INTO dts_route 
    (ROUTE_ID) 
SELECT dts_route_seq.NEXTVAL 
    FROM DUAL; 
Oracleは、今あなたがインクリメントするたびに「コミット」する必要があるため、パフォーマンスヒットがあることが

CREATE SEQUENCE dts_route_seq NOCACHE; 

注:その後、NOCACHE句を使用してシーケンスを作成し、あなたのルートのIDでそこにいるのギャップが心配な場合

+0

シーケンスでNOCACHEを必ず使用してください。絶対に1だけインクリメントする必要がある場合は、NOCACHEを使用してください。 – tbone

+0

@tbone:私がチャットした最後の人はテスト済みで、セッション全体で問題は見られませんでした。 –

+0

CACHEオプションを使用し、毎回+1を期待している人に警告を送信するだけです。私たちのDBAはパフォーマンスの向上を期待してキャッシュをオンにしました。代わりに、シーケンス番号が値をスキップしていたときにはそれほど素晴らしいことではありませんでした。 – tbone

関連する問題