2017-09-11 12 views
1

私はMySQLのLAST_INSERT_ID()関数が大好きです。私は、後で私のストアドプロシージャから返すためにちょうど挿入された行のIDを取得するために、常にそれを使用します。しかし、今私はDEFAULT CURRENT_TIMESTAMPに設定されている主キーとしてTIMESTAMPを持つテーブルを持っています。この最後に挿入されたタイムスタンプはどのように取得できますか?タイムスタンプのLAST_INSERT_IDに相当するものはありますか?

+1

同時挿入が同じCURRENT_TIMESTAMPを得た場合はどうなりますか?あなたはそれがあなたのpkの良い選択だと確信していますか? –

+1

@AlexK。営業時間はミリ秒の精度をタイムスタンプで使用している可能性がありますが、依然として競合の可能性はかなり高いです。挿入が頻繁に失敗し、再実行する必要があるため、良い選択ではありません。 –

+0

私は一般的に@BillKarwinに同意しますが、時間が本当に自然の識別子である(またはその一部である)場合があります。また、ユニークな制約を利用して、アプリまたはSProcを試してみてください。 「それは機能だ!」 –

答えて

4

これが安全にそれを行う必要があります。

START TRANSACTION; 
{do your insert}; 
SELECT MAX({timestamp field}) FROM {table}; 
COMMIT; 
+0

私は別の方法を提供しましたが、実際にはトランザクションでこれをやる方が好きです。数ヶ月で他の人(そして私自身)のために読むのが最も簡単です。 。 –

0

タイムスタンプフィールドでMAXメソッドを使用する。

+0

しかし、それはLAST_INSERT_IDのように並行処理は安全ではありませんか?なぜなら、IDのidフィールドでMAXメソッドを使用しないからです。 –

+1

@SimonBaars:反復可能な読み取りトランザクション分離を使用すると、トランザクションが開始されてから同時クライアントによって挿入された行はトランザクションに表示されません。 INSERTに失敗した場合、MAX()は値を返さないため、慎重にエラーをチェックする必要があります。 FWIWでは、プライマリキーとしてタイムスタンプを使用しません。競合する可能性が非常に高いからです。 –

+0

@SimonBaars私は 'LAST_INSERT_ID'が同じで、MAX IDを返します。 –

1

をそれについて移動する別の方法は、実際にあなたが好きな整数に値を設定することができる機能のLAST_INSERT_ID(expr)バージョン、(おそらくUNIX_TIMESTAMP整数を活用することですあなたのタイムスタンプ):?今

INSERT INTO my_tbl SET the_ts = FROM_UNIXTIME(LAST_INSERT_ID(UNIX_TIMESTAMP())); 

次のことができます。

SELECT FROM_UNIXTIME(LAST_INSERT_ID()); 

Jon Harmonが提供するトランザクションソリューションと同様に、この解決策の1つの欠点は、これを念頭に置いて(カラムのデフォルトを明示的に同じ値でオーバーライドするか、トランザクションを開始する)インサートに入る必要があることです。コードの可読性は少し低下し、この表を使用する他の人を混乱させる可能性があります。私は、Jonのソリューションは読みやすさを保つという点で優れていると思います。

また、あなたが引き金でこれをやっている場合ことに注意してください、triggers swallow last_insert_id() value changes.

は、しかし、あなたが本当にしたセッションVARを使用してトリガのうち、バブルそれを必要とすることができます。


LAST_INSERT_IDを設定するこの例を試してみてください。

SELECT FROM_UNIXTIME(LAST_INSERT_ID(UNIX_TIMESTAMP())); 
SELECT FROM_UNIXTIME(LAST_INSERT_ID()); 
+0

偉大な選択肢!ありがとう! –

関連する問題