MySQL में अंतिम अद्यतन पंक्ति की ID कैसे प्राप्त करें?


134

मुझे PHP का उपयोग करके MySQL में अंतिम अद्यतन पंक्ति की आईडी कैसे मिलेगी?


2
mysqli_insert_id ($ लिंक) बिल्कुल अंतिम अद्यतन पंक्ति की आईडी लौटाएगा। मैं इसी उद्देश्य के लिए अपनी परियोजनाओं में इस funtion का उपयोग कर रहा हूं। आप इसे सिंक्रोनस या एसिंक्रोनस प्रश्नों में उपयोग कर सकते हैं। बस $ lastupdated_row_id = mysqli_insert_id ($ लिंक) को अपने कोड में डालें और यह आपके लिए काम करेगा।
नईम उल वहाब

1
यदि आप अपडेट करते हैं तो क्या आप पहले से ही पंक्ति की आईडी नहीं जानते हैं? मुझे लगता है कि कुछ ऐसे मामले होने चाहिए जहाँ आप नहीं हैं।
JCharette

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. 13. धन्यवाद Pomyk, एक चतुर चाल!
जाका जानकर

1
चूँकि आपके पास एक WHEREक्लॉज़ है, आप WHEREअपनी अगली क्वेरी में बस एक ही क्लॉज़ का उपयोग कर सकते हैंSELECT id FROM footable WHERE fooid > 5
सलमान ए

4
शायद हर कोई इसे समझता है, लेकिन अगर आप mysql_query () का उपयोग करते हैं; आपको इसे तीन अलग-अलग कॉल में विभाजित करना होगा, लेकिन यह काम करेगा।
rael_kid

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();अपडेट की गई आईडी को वापस करेगा। अधिक विवरण के लिए newtover का उत्तर देखें।
जोएल

3
@SteveChilds मैं केवल newtover के प्रश्न पर टिप्पणी कर रहा था, और आपके द्वारा बताए जा रहे नुकसान के समाधान को जोड़ना चाहता हूं। यह LAST_INSERT_ID को 0 पर सेट करता है यदि कुछ अद्यतन नहीं है UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);:। हालाँकि यह कई आईडी को पुनर्प्राप्त नहीं करता है, इसलिए यह उत्तर बेहतर है।
Martinczerwi

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 जाँच के माध्यम से item_id का सशर्त अद्यतन जोड़ना होगा यदि डेटा पंक्ति में परिवर्तित होने जा रहा है।


3
यह बहु-उपयोगकर्ता सुरक्षित है क्योंकि कई क्लाइंट UPDATE स्टेटमेंट जारी कर सकते हैं और अपने स्वयं के अनुक्रम मान उत्पन्न करने वाले अन्य ग्राहकों को प्रभावित या प्रभावित किए बिना SELECT स्टेटमेंट (या mysql_insert_id ()) के साथ अपना स्वयं का अनुक्रम मान प्राप्त कर सकते हैं। Dev.mysql.com/doc/refman/5.0/en/… के
brutuscat

1
क्या यह अंतिम सम्मिलित रिकॉर्ड में item_id को सेट नहीं करेगा?
अर्लेस्ली

2
@arleslie, यदि आप ऊपर दिए गए ब्रूटसैट की टिप्पणी में डॉक्स के लिंक का अनुसरण करते हैं, तो आप देखेंगे कि यह नहीं होगा। यह वास्तव में मामले के लिए इच्छित व्यवहार है।
न्यूटेवर

1
यह वास्तव में सही उत्तर है। हालाँकि यह क्वेरी थोड़ी जवाबी लगती है, लेकिन यह वही है जो MySQL प्रलेखन करना कहते हैं।
टिमोथी ज़ोर्न

3
यदि क्वेरी आपको भ्रमित कर रही है, क्योंकि LAST_INSERT_ID (expr) UPDATE कॉल के लिए expr का मान लौटाएगा आप इसे इस तरह भी इस्तेमाल कर सकते हैं:UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
martinczerwi

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खंड लिए MySQL कह रहा है सेट मिली पंक्ति के आईडी को अपनी आंतरिक चर। जब आप last_insert_id(expr)इस तरह से एक मान पास करते हैं, तो यह उस मूल्य को वापस कर देता है, जो यहाँ की तरह आईडी के मामले में हमेशा एक सकारात्मक पूर्णांक होता है और इसलिए हमेशा सही का मूल्यांकन करता है, जहाँ कभी भी खंड के साथ हस्तक्षेप नहीं होता है। यह केवल तभी काम करता है जब कुछ पंक्ति वास्तव में पाई गई थी, इसलिए प्रभावित पंक्तियों की जांच करना याद रखें। फिर आप कई तरीकों से आईडी प्राप्त कर सकते हैं।

माई एसक्यूएल last_insert_id()

आप LAST_INSERT_ID () को कॉल किए बिना अनुक्रम उत्पन्न कर सकते हैं, लेकिन फ़ंक्शन का इस तरह उपयोग करने की उपयोगिता यह है कि सर्वर में आईडी मूल्य बनाए रखा जाता है क्योंकि अंतिम स्वचालित रूप से उत्पन्न मूल्य। यह बहु-उपयोगकर्ता सुरक्षित है क्योंकि कई क्लाइंट UPDATE स्टेटमेंट जारी कर सकते हैं और अपने स्वयं के अनुक्रम मान उत्पन्न करने वाले अन्य ग्राहकों को प्रभावित या प्रभावित किए बिना SELECT स्टेटमेंट (या mysql_insert_id ()) के साथ अपना स्वयं का अनुक्रम मान प्राप्त कर सकते हैं।

माई एसक्यूएल mysql_insert_id()

पिछले INSERT या अद्यतन कथन द्वारा AUTO_INCREMENT कॉलम के लिए उत्पन्न मान लौटाता है। किसी INSERT कथन को किसी तालिका में एक AUTO_INCREMENT फ़ील्ड शामिल करने के बाद, या LAST_INSERT_ID (expr) के साथ स्तंभ मान सेट करने के लिए 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();
}

(FYI करें कि DB क्लास यहाँ है ।)


नोट करना महत्वपूर्ण है: यह बहु-कनेक्शन सुरक्षित है, last_insert_id या mysql_insert_id (और शायद mysqli_insert_id, मैं जाँच नहीं किया था) के लिए निरंतर मूल्य, प्रति-कनेक्शन हैं। बहुत बढ़िया!
रयान एस

11

यह सलमान ए के जवाब के समान विधि है, लेकिन यहां कोड आपको वास्तव में करने की आवश्यकता है।

सबसे पहले, अपनी तालिका को संपादित करें ताकि जब भी कोई पंक्ति संशोधित हो, तो यह स्वचालित रूप से नज़र रखेगा। अंतिम पंक्ति को हटा दें यदि आप केवल यह जानना चाहते हैं कि एक पंक्ति शुरू में कब डाली गई थी।

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 मैनुअल में 'लास्ट मोडिफाइड टाइम' कॉलम को जोड़ना : सॉर्टिंग पंक्तियाँ । मैंने इसे इकट्ठा किया।


7
यदि पहली प्रविष्टि क्वेरी के ठीक बाद दूसरी प्रविष्टि की जाती है, तो यह विधि गलत आईडी ला सकती है। हालाँकि, यदि हम इस क्वेरी के साथ 'WHERE' का उपयोग करते हैं, यानी अंतिम बार से डिसएम्डिफाइड DESC लिमिट 1 WHERE (अंतिम इंसर्ट क्वेरी से संबंधित कुछ शर्तें) से सेलेक्ट आईडी से, तो यह गलत आईडी लाने से रोक सकता है।
नईम उल वहाब

1
@ नोबल-कोडर यह सच है। यदि आपको किसी विशेष अपडेट क्वेरी से प्रभावित पंक्ति की आईडी प्राप्त करने की आवश्यकता है, तो Pomyk की तकनीक का उपयोग करें। अतुल्यकालिक रूप से उपयोग किए जाने पर यहां यह तकनीक अधिक उपयोगी है, जहां आप पूर्ण अंतिम अपडेट चाहते हैं।
चाड वॉन नू

5

प्रश्न:

$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();
}

यह मेरे लिए काम है;)


मुझे वही पसंद आया लेकिन अलग

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;

मुझे आईडी (डननो क्यों) कास्ट करना था ... या मुझे @uids कंटेंट नहीं मिल सकता था (यह एक ब्लॉब था) Pomyk जवाब के लिए बहुत धन्यवाद!


2

अंतिम अद्यतन पंक्ति की ID वही ID होती है जिसका उपयोग आप उस पंक्ति को खोजने और अद्यतन करने के लिए 'updateQuery' में करते हैं। इसलिए, आप जिस भी आईडी पर चाहते हैं, बस उस आईडी को सेव (कॉल) करें।

last_insert_id()निर्भर करता है AUTO_INCREMENT, लेकिन अंतिम अपडेट की गई आईडी नहीं।


3
क्या होगा यदि अपडेट एक आईडी से नहीं किया गया है, बल्कि विशेषताओं का एक और सेट है?
सेबास

2

मेरा समाधान है, पहले "id" (@uids) को चुनिंदा कमांड से तय करें और बाद में इस आईडी को @uids के साथ अपडेट करें।

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

यह मेरे प्रोजेक्ट पर काम करता है।


1

यदि आप केवल प्रविष्टि कर रहे हैं, और एक ही सत्र से चाहते हैं, तो peirix के उत्तर के अनुसार करें। यदि आप संशोधन कर रहे हैं, तो आपको अपने डेटाबेस स्कीमा को संशोधित करने की आवश्यकता होगी कि कौन सी प्रविष्टि सबसे हाल ही में अपडेट की गई थी।

यदि आप अंतिम संशोधन से आईडी चाहते हैं, जो एक अलग सत्र से हो सकता है (यानी वह नहीं जो वर्तमान में चल रहे PHP कोड द्वारा किया गया था, लेकिन एक अलग अनुरोध के जवाब में किया गया है), आप जोड़ सकते हैं TIMESTAMP कॉलम आपकी तालिका में last_modified कहलाता है ( http://dev.mysql.com/doc/refman/5.1/en/datetime.html जानकारी के लिए देखें), और फिर जब आप अपडेट करते हैं, तो last_modified = CRARENT_TIME सेट करें।

इसे सेट करने के बाद, आप फिर एक क्वेरी का उपयोग कर सकते हैं जैसे: अंतिम आईडी से तालिका का चयन करें। सबसे हाल ही में संशोधित पंक्ति प्राप्त करने के लिए।


-9

इतने लंबे मैसकल कोड की आवश्यकता नहीं है। PHP में, क्वेरी को कुछ इस तरह दिखना चाहिए:

$updateQuery = mysql_query("UPDATE table_name SET row='value' WHERE id='$id'") or die ('Error');
$lastUpdatedId = mysql_insert_id();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.