আমি পিএইচপি ব্যবহার করে মাইএসকিউএল-এ সর্বশেষ আপডেট হওয়া সারির আইডি কীভাবে পাব?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1?
আমি পিএইচপি ব্যবহার করে মাইএসকিউএল-এ সর্বশেষ আপডেট হওয়া সারির আইডি কীভাবে পাব?
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;
সম্পাদনা aefxx দ্বারা
একটি আপডেট বিবৃতি দ্বারা প্রভাবিত প্রতিটি সারির আইডি পুনরুদ্ধার করতে এই কৌশলটি আরও বাড়ানো যেতে পারে:
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
এটি কমা দ্বারা সংযুক্ত সমস্ত আইডি সহ একটি স্ট্রিং ফিরিয়ে দেবে।
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();আপডেট করা আইডি ফিরিয়ে দেবে। আরও তথ্যের জন্য নতুনদের উত্তর দেখুন।
UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);। তবে এটি একাধিক আইডিকে পুনরুদ্ধার করে না, সুতরাং এই উত্তরটি সর্বোত্তম।
এইচএম, আমি অবাক হয়েছি যে উত্তরগুলির মধ্যে আমি সবচেয়ে সহজ সমাধানটি দেখতে পাচ্ছি না।
ধরুন, 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- এর মাধ্যমে আইটেম_আইডির শর্তসাপেক্ষ আপডেট যুক্ত করা দরকার যদি তথ্যটি সারিটিতে পরিবর্তন হতে চলেছে।
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অনুচ্ছেদের মাইএসকিউএল বলছে সেট পাওয়া সারির আইডি তার অভ্যন্তরীণ পরিবর্তনশীল। আপনি যখন last_insert_id(expr)এটি পছন্দ করার জন্য কোনও মান পাস করেন , তখন সেই মানটি ফিরে আসে, যা এখানে আইডির ক্ষেত্রে সর্বদা একটি ধনাত্মক পূর্ণসংখ্যার এবং তাই সর্বদা সত্যের কাছে মূল্যায়ন করে, যেখানে কোনও ধারাটিতে হস্তক্ষেপ না করে। এটি কেবল তখনই কাজ করে যদি কিছু সারি আসলে পাওয়া যায়, সুতরাং প্রভাবিত সারিগুলি পরীক্ষা করতে ভুলবেন না remember তারপরে আপনি একাধিক উপায়ে আইডি পেতে পারেন।
আপনি LAST_INSERT_ID () না কল করে সিকোয়েন্স তৈরি করতে পারেন, তবে এইভাবে ফাংশনটি ব্যবহারের উপযোগটি হ'ল আইডি মানটি সর্বশেষে স্বয়ংক্রিয়ভাবে উত্পন্ন মান হিসাবে সার্ভারে বজায় থাকে। এটি মাল্টি-ব্যবহারকারী নিরাপদ কারণ একাধিক ক্লায়েন্টগুলি তাদের নিজস্ব ক্রম মানগুলি উত্পন্ন করে এমন অন্য ক্লায়েন্টদের দ্বারা প্রভাবিত বা প্রভাবিত না করে SELECT স্টেটমেন্ট (বা 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 কলামে কী ঘটে সে সম্পর্কে আরও সঠিক তথ্য সরবরাহ করার চেষ্টা করে।
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();
}
(এফওয়াইআই যে ডিবি ক্লাস এখানে রয়েছে ))
এটি সালমান এ-এর উত্তরের মতো একই পদ্ধতি, তবে আপনার কোডটি আসলে এটি করা দরকার।
প্রথমে আপনার টেবিলটি সম্পাদনা করুন যাতে এটি যখনই কোনও সারি পরিবর্তিত হয় তখন তা স্বয়ংক্রিয়ভাবে ট্র্যাক করে রাখে। আপনি যদি কেবল সারি শুরুতে কখন সন্নিবেশ করানো হয় কেবল তা জানতে চাইলে শেষ লাইনটি সরিয়ে ফেলুন।
ALTER TABLE mytable
ADD lastmodified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
তারপরে, সর্বশেষ আপডেট হওয়া সারিটি জানতে, আপনি এই কোডটি ব্যবহার করতে পারেন।
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
এই কোডটি মাইএসকিউএল বনাম পোস্টগ্রেএসকিউএল থেকে তোলা হয়েছে: একটি টেবিলে একটি 'শেষ পরিবর্তিত সময়' কলাম যুক্ত করা হচ্ছে এবং মাইএসকিউএল ম্যানুয়াল: সারিগুলি বাছাই করা হচ্ছে । আমি শুধু এটি একত্রিত।
প্রশ্ন :
$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();
}
এটা আমার জন্য কাজ;)
উপরে গৃহীত উত্তরের আরও আরও
যারা তাদের সম্পর্কে :=&=
:=এবং এর মধ্যে উল্লেখযোগ্য পার্থক্য =এবং এটি হ'ল :=সর্বত্র চলক-অ্যাসাইনমেন্ট অপারেটর হিসাবে কাজ করে= কেবল সেটের বিবৃতিতে সেভাবে কাজ করে এবং অন্য কোথাও একটি তুলনামূলক অপারেটর।
তাই SELECT @var = 1 + 1;ছাড়বে @varঅপরিবর্তিত এবং একটি ফিরতি বুলিয়ান (1 বা 0 @var বর্তমান মূল্য উপর নির্ভর করে), যখন SELECT @var := 1 + 1;পরিবর্তন করা হবে @varথেকে 2 , এবং আসতে 2 ।
[উৎস]
আরে, আমার কেবল এমন কৌশলটি দরকার ছিল - আমি এটি অন্যভাবে সমাধান করেছি, সম্ভবত এটি আপনার পক্ষে কার্যকর হবে। নোট করুন এটি কোনও স্কেলযোগ্য সমাধান নয় এবং বড় ডেটা সেটগুলির জন্য খুব খারাপ।
আপনার ক্যোয়ারিকে দুটি ভাগে ভাগ করুন -
প্রথমে আপনি যে সারিগুলির আপডেট করতে চান সেগুলির আইডিকে নির্বাচন করুন এবং এগুলি একটি অস্থায়ী সারণীতে সংরক্ষণ করুন।
দ্বিতীয়ত, আপডেট বিবৃতিতে অবস্থিত শর্তটি সহ অরিজিনাল আপডেট করুন where id in temp_table।
এবং একত্রীকরণ নিশ্চিত করতে, আপনাকে এই দুটি পদক্ষেপের আগে টেবিলটি লক করতে হবে এবং তারপরে লকটি শেষে ছেড়ে দিতে হবে।
আবার, এটি আমার জন্য একটি ক্যোয়ারির জন্য কাজ করে যা শেষ হয় limit 1, তাই আমি কোনও টেম্প টেবিলও ব্যবহার করি না, বরং প্রথমটির ফলাফল সংরক্ষণের জন্য কেবল একটি পরিবর্তনশীল select।
আমি এই পদ্ধতিটি পছন্দ করি যেহেতু আমি জানি আমি সর্বদা কেবল একটি সারি আপডেট করব এবং কোডটি সোজা।
সর্বশেষ আপডেট হওয়া সারির আইডি হ'ল সেই আইডি যা আপনি 'সার্টিফিকেটওয়্যার' ব্যবহার করে সেই সারিটি খুঁজে পেতে এবং আপডেট করতে পারেন। সুতরাং, যেভাবে আপনি চান সেই আইডিটি কেবল সংরক্ষণ করুন (কল করুন)।
last_insert_id()নির্ভর করে AUTO_INCREMENT, তবে সর্বশেষ আপডেট হওয়া আইডি নয়।
আপনি যদি কেবল সন্নিবেশ করছেন এবং একই অধিবেশন থেকে একটি চান, পিরিক্সের উত্তর অনুযায়ী করুন। আপনি যদি সংশোধন করে থাকেন তবে কোন এন্ট্রিটি সম্প্রতি আপডেট হয়েছিল তা সংরক্ষণ করার জন্য আপনার ডাটাবেস স্কিমাটি পরিবর্তন করতে হবে।
আপনি যদি সর্বশেষ পরিবর্তনটি থেকে আইডিটি চান, যা অন্য কোনও অধিবেশন হতে পারে (যেমন বর্তমানে পিএইচপি কোড চলমান নয়, তবে একটি ভিন্ন অনুরোধের জবাবে করা হয়েছে), আপনি যুক্ত করতে পারেন আপনার টেবিলে TIMESTAMP কলামটি সর্বশেষ_মাংসিত বলা হয় (তথ্যের জন্য http://dev.mysql.com/doc/refman/5.1/en/datetime.html দেখুন ), এবং তারপরে আপনি আপডেট করার সময় শেষ_মোডিফাড = CURRENT_TIME সেট করুন।
এটি সেট করার পরে, আপনি এরপরে একটি কোয়েরি ব্যবহার করতে পারেন: শেষ_মাংস্কারিত ডিইএসসি লিমিটেড 1 এর মাধ্যমে টেবিলের অর্ডার থেকে নির্বাচন করুন; সর্বাধিক সংশোধিত সারিটি পেতে।