মাইএসকিউএল-এ সর্বশেষ আপডেট হওয়া সারির আইডি কীভাবে পাবেন?


134

আমি পিএইচপি ব্যবহার করে মাইএসকিউএল-এ সর্বশেষ আপডেট হওয়া সারির আইডি কীভাবে পাব?


2
mysqli_insert_id ($ লিঙ্ক) সর্বশেষ আপডেট হওয়া সারির আইডিটি আসবে। আমি আমার প্রকল্পগুলিতে এই উদ্দেশ্যটিকে একই উদ্দেশ্যে ব্যবহার করছি using আপনি এটিকে সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস কোয়েরিতে উভয়ই ব্যবহার করতে পারেন। আপনার কোডটিতে স্রেফ $ সর্বশেষতম_রো_আইডি = মাইসকিলি_ইন_টারেট (আইডি) sertোকান এবং এটি আপনার পক্ষে কাজ করবে।
উল ওয়াহাব

1
আপনি আপডেট হলে সারিটির আইডি ইতিমধ্যে জানেন না? আমি অনুমান করি এমন কিছু মামলা অবশ্যই আছে যেখানে আপনি করেন না।
জেচারেট ২

1
আপনি সম্ভবত আপনার আপডেট ক্যোয়ারিতে এমন একটি ক্লজ ব্যবহার করেছেন, আপনি কেন নির্বাচিত ক্যোয়ারিতে ধারাটি ব্যবহার করতে পারবেন না? UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1?
সালমান এ

উত্তর:


236

আমি এই সমস্যার উত্তর পেয়েছি :)

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;

সম্পাদনা aefxx দ্বারা

একটি আপডেট বিবৃতি দ্বারা প্রভাবিত প্রতিটি সারির আইডি পুনরুদ্ধার করতে এই কৌশলটি আরও বাড়ানো যেতে পারে:

SET @uids := null;
UPDATE footable
   SET foo = 'bar'
 WHERE fooid > 5
   AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;

এটি কমা দ্বারা সংযুক্ত সমস্ত আইডি সহ একটি স্ট্রিং ফিরিয়ে দেবে।


6
বিশ্বাস করতে পারছে না এটির 0 টি upvotes ছিল, এবং mysql_insert_id () মন্তব্যটি যা ওপি মোটামুটি জিজ্ঞাসা করছে না 13 রয়েছে Thanks ধন্যবাদ পোমিক, একটি চতুর কৌশল!
জাকা জানার

1
আপনার যেহেতু একটি WHEREধারা রয়েছে তাই আপনি WHEREআপনার পরবর্তী প্রশ্নের মধ্যে একই ধারাটি কেবল ব্যবহার করতে পারেনSELECT id FROM footable WHERE fooid > 5
সালমান এ

4
হয়তো প্রত্যেকে এটি বুঝতে পারে তবে আপনি যদি mysql_query () ব্যবহার করেন; আপনাকে এটিকে তিনটি ভিন্ন কলগুলিতে ভাগ করতে হবে, তবে এটি কার্যকর হবে।
rael_kid 15'15

8
এমনকি ভেরিয়েবলগুলি ব্যবহার করার প্রয়োজন নেই। LAST_INSERT_ID()একটি আর্গুমেন্ট গ্রহণ করতে পারে যা পরের কলটিতে ফিরে আসা মান সেট করবে LAST_INSERT_ID()। উদাহরণস্বরূপ: UPDATE table SET id=LAST_INSERT_ID(id), row='value' WHERE other_row='blah';। এখন, SELECT LAST_INSERT_ID();আপডেট করা আইডি ফিরিয়ে দেবে। আরও তথ্যের জন্য নতুনদের উত্তর দেখুন।
জোয়েল

3
@ স্টিভহিল্ডস আমি কেবলমাত্র নতুনদের প্রশ্নের মন্তব্য করছি, এবং আপনি যে সমস্যার বর্ণনা দিচ্ছেন তার একটি সমাধান যুক্ত করতে চাই। এই সেট 0 LAST_INSERT_ID আপডেট করার জন্য কিছু নেই যদি: UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);। তবে এটি একাধিক আইডিকে পুনরুদ্ধার করে না, সুতরাং এই উত্তরটি সর্বোত্তম।
মার্টিনজার্জিবি

33

এইচএম, আমি অবাক হয়েছি যে উত্তরগুলির মধ্যে আমি সবচেয়ে সহজ সমাধানটি দেখতে পাচ্ছি না।

ধরুন, item_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- এর মাধ্যমে আইটেম_আইডির শর্তসাপেক্ষ আপডেট যুক্ত করা দরকার যদি তথ্যটি সারিটিতে পরিবর্তন হতে চলেছে।


3
এটি মাল্টি-ব্যবহারকারী নিরাপদ কারণ একাধিক ক্লায়েন্টগুলি তাদের নিজস্ব ক্রম মানগুলি উত্পন্ন করে এমন অন্য ক্লায়েন্টদের দ্বারা প্রভাবিত বা প্রভাবিত না করে SELECT স্টেটমেন্ট (বা mysql_insert_id ()) এর সাথে তাদের নিজস্ব ক্রম মান পেতে পারে। হিসাবে প্রতি dev.mysql.com/doc/refman/5.0/en/...
brutuscat

1
এটি কি সর্বশেষ sertedোকানো রেকর্ডে আইটেম_আইডি সেট করবে না?
আরলেসেলি

2
@ আরলেস্লি, যদি আপনি উপরের বুরুস্কাটের মন্তব্যে ডক্সের লিঙ্কটি অনুসরণ করেন তবে আপনি দেখতে পাবেন এটি হবে না। এটি হ'ল মামলার উদ্দেশ্যমূলক আচরণ।
নতুন

1
এটি সত্যই সঠিক উত্তর। যদিও ক্যোয়ারীটি কিছুটা স্ব-স্বজ্ঞাত বলে মনে হচ্ছে, এটি মাইএসকিউএল ডকুমেন্টেশনটি ঠিক তাই করেছে।
টিমোথি জর্ন

3
যদি প্রশ্নটি আপনাকে বিভ্রান্ত করছে, যেহেতু LAST_INSERT_ID (এক্সপ্রেস) আপডেটের কলটির জন্য এক্সপ্রেসের মান ফেরত দেবে আপনি এটিও এটি ব্যবহার করতে পারেন:UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
মার্টিনজার্জারভি

14

এটি সরকারীভাবে সরল তবে লক্ষণীয়ভাবে স্ব-স্বজ্ঞাত। আপনি যদি করছেন:

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অনুচ্ছেদের মাইএসকিউএল বলছে সেট পাওয়া সারির আইডি তার অভ্যন্তরীণ পরিবর্তনশীল। আপনি যখন last_insert_id(expr)এটি পছন্দ করার জন্য কোনও মান পাস করেন , তখন সেই মানটি ফিরে আসে, যা এখানে আইডির ক্ষেত্রে সর্বদা একটি ধনাত্মক পূর্ণসংখ্যার এবং তাই সর্বদা সত্যের কাছে মূল্যায়ন করে, যেখানে কোনও ধারাটিতে হস্তক্ষেপ না করে। এটি কেবল তখনই কাজ করে যদি কিছু সারি আসলে পাওয়া যায়, সুতরাং প্রভাবিত সারিগুলি পরীক্ষা করতে ভুলবেন না remember তারপরে আপনি একাধিক উপায়ে আইডি পেতে পারেন।

মাইএসকিউএল last_insert_id()

আপনি LAST_INSERT_ID () না কল করে সিকোয়েন্স তৈরি করতে পারেন, তবে এইভাবে ফাংশনটি ব্যবহারের উপযোগটি হ'ল আইডি মানটি সর্বশেষে স্বয়ংক্রিয়ভাবে উত্পন্ন মান হিসাবে সার্ভারে বজায় থাকে। এটি মাল্টি-ব্যবহারকারী নিরাপদ কারণ একাধিক ক্লায়েন্টগুলি তাদের নিজস্ব ক্রম মানগুলি উত্পন্ন করে এমন অন্য ক্লায়েন্টদের দ্বারা প্রভাবিত বা প্রভাবিত না করে SELECT স্টেটমেন্ট (বা mysql_insert_id ()) এর সাথে তাদের নিজস্ব ক্রম মান পেতে পারে।

মাইএসকিউএল mysql_insert_id()

পূর্ববর্তী INSERT বা আপডেটের বিবৃতি দ্বারা AUTO_INCREMENT কলামের জন্য উত্পন্ন মানটি দেয়। আপনি একটি টেবিলের মধ্যে একটি INSERT বিবৃতি সঞ্চালনের পরে এই ফাংশনটি ব্যবহার করুন যার মধ্যে একটি AUTO)CREMENT ক্ষেত্র রয়েছে, বা LAST_INSERT_ID (এক্সপ্রেস) দিয়ে একটি কলাম মান সেট করতে INSERT বা UPDATE ব্যবহার করেছেন।

LAST_INSERT_ID () এবং mysql_insert_id () এর মধ্যে পার্থক্যের কারণ হ'ল LAST_INSERT_ID () স্ক্রিপ্টগুলিতে ব্যবহার করা সহজ করা হয়েছে যখন mysql_insert_id () AUTO_INCREMENT কলামে কী ঘটে সে সম্পর্কে আরও সঠিক তথ্য সরবরাহ করার চেষ্টা করে।

পিএইচপি mysqli_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();
}

(এফওয়াইআই যে ডিবি ক্লাস এখানে রয়েছে ))


গুরুত্বপূর্ণ লক্ষণীয়: এটি মাল্টি-সংযোগ নিরাপদ, লাস্ট_ইনটার_আইডি বা মাইএসকিএল_ইন_টার_র জন্য অবিচ্ছিন্ন মান (এবং হতে পারে mysqli_insert_id, আমি চেক করিনি), প্রতি সংযোগ। অসাধারণ!
রায়ান এস

10

এটি সালমান এ-এর উত্তরের মতো একই পদ্ধতি, তবে আপনার কোডটি আসলে এটি করা দরকার।

প্রথমে আপনার টেবিলটি সম্পাদনা করুন যাতে এটি যখনই কোনও সারি পরিবর্তিত হয় তখন তা স্বয়ংক্রিয়ভাবে ট্র্যাক করে রাখে। আপনি যদি কেবল সারি শুরুতে কখন সন্নিবেশ করানো হয় কেবল তা জানতে চাইলে শেষ লাইনটি সরিয়ে ফেলুন।

ALTER TABLE mytable
ADD lastmodified TIMESTAMP 
    DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP;

তারপরে, সর্বশেষ আপডেট হওয়া সারিটি জানতে, আপনি এই কোডটি ব্যবহার করতে পারেন।

SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;

এই কোডটি মাইএসকিউএল বনাম পোস্টগ্রেএসকিউএল থেকে তোলা হয়েছে: একটি টেবিলে একটি 'শেষ পরিবর্তিত সময়' কলাম যুক্ত করা হচ্ছে এবং মাইএসকিউএল ম্যানুয়াল: সারিগুলি বাছাই করা হচ্ছে । আমি শুধু এটি একত্রিত।


7
প্রথম সন্নিবেশ ক্যোয়ারির ঠিক পরে দ্বিতীয় সন্নিবেশ করা হলে এই পদ্ধতিটি ভুল আইডি আনতে পারে। তবে আমরা যদি এই ক্যোয়ারির সাথে 'WHERE' ব্যবহার করি অর্থাৎ শেষ পরিবর্তিত DESC লিমিটেড 1 যেখানে (সর্বশেষ সন্নিবেশ অনুসন্ধানের সাথে সম্পর্কিত কিছু শর্তাবলীর) দ্বারা আইডি নির্বাচন করুন, তবে এটি ভুল আইডি আনতে বাধা দিতে পারে।
উল ওহাব

1
@ দ্য নোবল-কোডার এটি সত্য। আপনার যদি কোনও সারির আইডি পেতে কোনও নির্দিষ্ট আপডেটের ক্যোয়ারীকে প্রভাবিত করে, তবে পোমিকের কৌশলটি ব্যবহার করুন। অবিচ্ছিন্নভাবে ব্যবহার করা হলে এখানে এই কৌশলটি বেশি কার্যকর where যেখানে আপনি কেবল সর্বশেষ আপডেট চান।
চাদ ভন নউ

5

প্রশ্ন :

$sqlQuery = "UPDATE 
            update_table 
        SET 
            set_name = 'value' 
        WHERE 
            where_name = 'name'
        LIMIT 1;";

পিএইচপি ফাংশন:

function updateAndGetId($sqlQuery)
{
    mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
    return mysql_insert_id();
}

এটা আমার জন্য কাজ;)


আমি একই পছন্দ করেছিলাম তবে পৃথকভাবে

3

উপরে গৃহীত উত্তরের আরও আরও
যারা তাদের সম্পর্কে :=&=

:=এবং এর মধ্যে উল্লেখযোগ্য পার্থক্য =এবং এটি হ'ল :=সর্বত্র চলক-অ্যাসাইনমেন্ট অপারেটর হিসাবে কাজ করে= কেবল সেটের বিবৃতিতে সেভাবে কাজ করে এবং অন্য কোথাও একটি তুলনামূলক অপারেটর।

তাই SELECT @var = 1 + 1;ছাড়বে @varঅপরিবর্তিত এবং একটি ফিরতি বুলিয়ান (1 বা 0 @var বর্তমান মূল্য উপর নির্ভর করে), যখন SELECT @var := 1 + 1;পরিবর্তন করা হবে @varথেকে 2 , এবং আসতে 2 [উৎস]


হেই ধন্যবাদ. তারা যা বোঝায় তা আসলে উপরোক্ত গৃহীত উত্তরের চেয়ে আরও আকর্ষণীয়।
সবুজ

2

আরে, আমার কেবল এমন কৌশলটি দরকার ছিল - আমি এটি অন্যভাবে সমাধান করেছি, সম্ভবত এটি আপনার পক্ষে কার্যকর হবে। নোট করুন এটি কোনও স্কেলযোগ্য সমাধান নয় এবং বড় ডেটা সেটগুলির জন্য খুব খারাপ।

আপনার ক্যোয়ারিকে দুটি ভাগে ভাগ করুন -

প্রথমে আপনি যে সারিগুলির আপডেট করতে চান সেগুলির আইডিকে নির্বাচন করুন এবং এগুলি একটি অস্থায়ী সারণীতে সংরক্ষণ করুন।

দ্বিতীয়ত, আপডেট বিবৃতিতে অবস্থিত শর্তটি সহ অরিজিনাল আপডেট করুন where id in temp_table

এবং একত্রীকরণ নিশ্চিত করতে, আপনাকে এই দুটি পদক্ষেপের আগে টেবিলটি লক করতে হবে এবং তারপরে লকটি শেষে ছেড়ে দিতে হবে।

আবার, এটি আমার জন্য একটি ক্যোয়ারির জন্য কাজ করে যা শেষ হয় limit 1, তাই আমি কোনও টেম্প টেবিলও ব্যবহার করি না, বরং প্রথমটির ফলাফল সংরক্ষণের জন্য কেবল একটি পরিবর্তনশীল select

আমি এই পদ্ধতিটি পছন্দ করি যেহেতু আমি জানি আমি সর্বদা কেবল একটি সারি আপডেট করব এবং কোডটি সোজা।


2
SET @uids := "";
UPDATE myf___ingtable
   SET id = id
   WHERE id < 5
  AND ( SELECT @uids := CONCAT_WS(',', CAST(id AS CHAR CHARACTER SET utf8), @uids) );
SELECT @uids;

আমাকে আইডিটি কাস্ট করতে হয়েছিল (কেনো ডুনো) ... বা আমি পেলাম উত্তরগুলির জন্য বিউডব্লিউ অনেক ধন্যবাদ!


2

সর্বশেষ আপডেট হওয়া সারির আইডি হ'ল সেই আইডি যা আপনি 'সার্টিফিকেটওয়্যার' ব্যবহার করে সেই সারিটি খুঁজে পেতে এবং আপডেট করতে পারেন। সুতরাং, যেভাবে আপনি চান সেই আইডিটি কেবল সংরক্ষণ করুন (কল করুন)।

last_insert_id()নির্ভর করে AUTO_INCREMENT, তবে সর্বশেষ আপডেট হওয়া আইডি নয়।


3
আপডেটটি যদি কোনও আইডি থেকে না হয়ে বরং আরও একটি বৈশিষ্ট্যের সেট থেকে করা হয় তবে কী হবে?
সেবাস

2

আমার সমাধানটি হল, প্রথমে নির্বাচিত কমান্ডের সাথে "আইডি" (@ উইডস) সিদ্ধান্ত নিন এবং @ আইডিসহ এই আইডিটি আপডেট করার পরে।

SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;

এটি আমার প্রকল্পে কাজ করেছে।


1

আপনি যদি কেবল সন্নিবেশ করছেন এবং একই অধিবেশন থেকে একটি চান, পিরিক্সের উত্তর অনুযায়ী করুন। আপনি যদি সংশোধন করে থাকেন তবে কোন এন্ট্রিটি সম্প্রতি আপডেট হয়েছিল তা সংরক্ষণ করার জন্য আপনার ডাটাবেস স্কিমাটি পরিবর্তন করতে হবে।

আপনি যদি সর্বশেষ পরিবর্তনটি থেকে আইডিটি চান, যা অন্য কোনও অধিবেশন হতে পারে (যেমন বর্তমানে পিএইচপি কোড চলমান নয়, তবে একটি ভিন্ন অনুরোধের জবাবে করা হয়েছে), আপনি যুক্ত করতে পারেন আপনার টেবিলে TIMESTAMP কলামটি সর্বশেষ_মাংসিত বলা হয় (তথ্যের জন্য http://dev.mysql.com/doc/refman/5.1/en/datetime.html দেখুন ), এবং তারপরে আপনি আপডেট করার সময় শেষ_মোডিফাড = CURRENT_TIME সেট করুন।

এটি সেট করার পরে, আপনি এরপরে একটি কোয়েরি ব্যবহার করতে পারেন: শেষ_মাংস্কারিত ডিইএসসি লিমিটেড 1 এর মাধ্যমে টেবিলের অর্ডার থেকে নির্বাচন করুন; সর্বাধিক সংশোধিত সারিটি পেতে।


-9

এত দীর্ঘ মাইএসকিএল কোডের দরকার নেই। পিএইচপি-তে, ক্যোয়ারির মতো কিছু দেখতে পাওয়া উচিত:

$updateQuery = mysql_query("UPDATE table_name SET row='value' WHERE id='$id'") or die ('Error');
$lastUpdatedId = mysql_insert_id();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.