dポイントプレゼントキャンペーン実施中!

前提:ORACLE

「一番古いレコードを取得する。」というのが条件です。
これを満たすだけであればSEQENCE等で連番を振れば満たせます。
しかし、日付時刻+連番であればカラム一つで時刻まで把握できます。
(日付時刻を利用することはありませんが、付加価値?として。)

というわけで、日付時刻+連番(桁固定のサイクリック)の主キーを使いたいのですが、
以下のように同時刻で連番が先頭に戻ると順番が守れません。
時刻A9999
時刻A0000 ← あとから挿入したのに同時刻の先頭になる

プログラムであれば同時刻なら連番を先頭から使うことも簡単ですが、
このよなことをSQL側だけでできるのでしょうか?

よろしくお願いします。

A 回答 (2件)

シーケンスを使う方法としては、1分以内に9999を超えることがないなら、


シーケンスを1分毎に0にリセットして使えばいいと思いますし、
他の方法としては、
連番 = (select nvl((select max(連番)+ 1 from テーブル
where 連番 like to_char(sysdate,'hhmiss') || 'A%')
,to_char(sysdate,'hhmiss') || 'A0001')
from dual)
で既に登録されたデータに1を加えてもいいと思いますが。

※どちらも秒単位で連番という仕様で書いています。
 単に連番で付けている番号だけでサイクリックにすると質問の現象は防げません。
 (防ぐためには、サイクリックにはできません。どこかでリセットするか十分に大きな桁数をとるか
  いづれかが必要です。)

なお、同時に複数のコミットされていないデータが発生する
(DB側が、2CPU以上で同時に処理されている)というのなら、不可能。
(複数のCPUをまたいで連番を共有することはプログラムでもできっこないです。)
・・・2CPU以上で同時に処理されているのでなければミリ秒まで同一のデータが出来るのは
あまり起きないと思うのですが。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
SQLだけでは難しそうですね。
参考にさせて頂きます。

お礼日時:2013/12/29 19:46

なぜ主キーで判断しようとするのか?


レコード作成日時の列をTIMESTAMP型・デフォルト設定じゃダメなの?

TIMESTAMP型ならミリ秒までの精度がありますよ。

この回答への補足

回答ありがとうございます。

ミリ秒では重複する可能性が高いのでTIMESTAMP型そのままでは使えません。
連番を主キーにして、TIMESTAMP型のカラムも用意すればレコード作成日時はわかりますが、
質問にもあるようにレコード作成日時は使用しません。

補足日時:2013/12/15 14:43
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す