PHPを使用してMySQLで最後に更新された行のIDを取得するにはどうすればよいですか?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?
PHPを使用してMySQLで最後に更新された行のIDを取得するにはどうすればよいですか?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?
回答:
私はこの問題の答えを見つけました:)
SET @update_id := 0;
UPDATE some_table SET column_name = 'value', id = (SELECT @update_id := id)
WHERE some_other_column = 'blah' LIMIT 1;
SELECT @update_id;
EDIT aefxxによって
この手法をさらに拡張して、更新ステートメントの影響を受けるすべての行のIDを取得できます。
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
これは、すべてのIDがコンマで連結された文字列を返します。
WHERE
句を、あなたは、単に同じ使用することができますWHERE
あなたの次のクエリでWHERE句をSELECT id FROM footable WHERE fooid > 5
LAST_INSERT_ID()
次のの呼び出しで返される値を設定する引数を受け入れることができLAST_INSERT_ID()
ます。例:UPDATE table SET id=LAST_INSERT_ID(id), row='value' WHERE other_row='blah';
。これでSELECT LAST_INSERT_ID();
、更新されたIDが返されます。詳細については、newtoverの回答を参照してください。
UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);
。ただし、複数のIDを取得しないため、この答えの方が優れています。
ええと、私は答えの中で最も簡単な解決策を見つけられないことに驚いています。
仮定し、item_id
整数のID列でitems
テーブルと次の文を使用して行を更新します。
UPDATE items
SET qwe = 'qwe'
WHERE asd = 'asd';
次に、ステートメントの直後に影響を受ける最新の行を知るには、ステートメントを次のように少し更新する必要があります。
UPDATE items
SET qwe = 'qwe',
item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();
実際に変更された行のみを更新する必要がある場合、データが行で変更されるかどうかをLAST_INSERT_IDチェックを介してitem_idの条件付き更新を追加する必要があります。
UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
これは公式にはシンプルですが、直感に反します。あなたがやっている場合:
update users set status = 'processing' where status = 'pending'
limit 1
これを次のように変更します。
update users set status = 'processing' where status = 'pending'
and last_insert_id(user_id)
limit 1
句のの追加はlast_insert_id(user_id)
、where
MySQLにその内部変数を見つかった行のID に設定するように指示しています。last_insert_id(expr)
このように値を渡すと、最終的にその値が返されます。このようなIDの場合、これは常に正の整数であるため、常にtrueと評価され、where句に干渉しません。これは実際に一部の行が見つかった場合にのみ機能するため、影響を受ける行を必ず確認してください。その後、複数の方法でIDを取得できます。
LAST_INSERT_ID()を呼び出さなくてもシーケンスを生成できますが、このように関数を使用することの有用性は、ID値が最後に自動生成された値としてサーバーに保持されることです。複数のクライアントがUPDATEステートメントを発行してSELECTステートメント(またはmysql_insert_id())で独自のシーケンス値を取得できるため、独自のシーケンス値を生成する他のクライアントに影響を与えたり、影響を受けたりすることがないため、マルチユーザーセーフです。
以前のINSERTまたはUPDATEステートメントによってAUTO_INCREMENT列に生成された値を返します。AUTO_INCREMENTフィールドを含むテーブルに対してINSERTステートメントを実行した後、またはINSERTまたはUPDATEを使用してLAST_INSERT_ID(expr)で列の値を設定した後に、この関数を使用します。
LAST_INSERT_ID()とmysql_insert_id()の違いの理由は、mysql_insert_id()がAUTO_INCREMENTカラムで何が起こっているかについてより正確な情報を提供しようとする一方で、LAST_INSERT_ID()がスクリプトで簡単に使用できるためです。
LAST_INSERT_ID()関数を使用してINSERTまたはUPDATEステートメントを実行すると、mysqli_insert_id()関数によって返される値も変更されます。
すべてを一緒に入れて:
$affected_rows = DB::getAffectedRows("
update users set status = 'processing'
where status = 'pending' and last_insert_id(user_id)
limit 1"
);
if ($affected_rows) {
$user_id = DB::getInsertId();
}
(参考:DBクラスはこちらです。)
これはSalman Aの回答と同じ方法ですが、実際に必要なコードは次のとおりです。
まず、テーブルを編集して、行が変更されるたびに自動的に追跡されるようにします。行が最初にいつ挿入されたかだけを知りたい場合は、最後の行を削除してください。
ALTER TABLE mytable
ADD lastmodified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
次に、最後に更新された行を見つけるために、このコードを使用できます。
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
このコードはすべて、MySQLとPostgreSQL:テーブルへの「最終変更時刻」列の追加とMySQLマニュアル:行のソートから引き上げられています。組み立てたところです。
クエリ:
$sqlQuery = "UPDATE
update_table
SET
set_name = 'value'
WHERE
where_name = 'name'
LIMIT 1;";
PHP関数:
function updateAndGetId($sqlQuery)
{
mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
return mysql_insert_id();
}
それは私にとっては仕事です;)
ちょっと、私はそのようなトリックが必要だった-私は別の方法でそれを解決しました、多分それはあなたのために働くでしょう。これはスケーラブルなソリューションではなく、大きなデータセットの場合は非常に悪いことに注意してください。
クエリを2つの部分に分割します-
まず、更新する行のIDを選択し、一時テーブルに保存します。
次に、更新ステートメントの条件をに変更して、元の更新を実行しwhere id in temp_table
ます。
そして、同時性を確保するために、あなたがする必要がロックし、この二つのステップの前にテーブルをして、最後にロックを解除します。
繰り返しますが、これはで終わるクエリで機能します。そのlimit 1
ため、一時テーブルも使用せず、最初のの結果を格納するための変数を使用しますselect
。
私は常に1行のみを更新することがわかっているため、この方法を使用します。コードは単純です。
挿入のみを行い、同じセッションから挿入したい場合は、Peirixの回答に従ってください。変更を行う場合は、データベーススキーマを変更して、最後に更新されたエントリを格納する必要があります。
別のセッションからのものである可能性がある最後の変更のIDが必要な場合(つまり、現在実行中のPHPコードによって実行されたIDではなく、別の要求に応答して実行されたID)、次を追加できます。 last_modifiedと呼ばれるテーブルへのTIMESTAMP列(http://dev.mysql.com/doc/refman/5.1/en/datetime.htmlを参照してください)。次に、更新するときに、last_modified = CURRENT_TIMEを設定します。
これを設定したら、次のようなクエリを使用できます。SELECT id FROM table ORDER BY last_modified DESC LIMIT 1; 最後に変更された行を取得します。