মাইএসকিউএল অন ডুপ্লিকেট কী - শেষ আইডি sertোকানো?


132

আমার নিম্নলিখিত জিজ্ঞাসা রয়েছে:

INSERT INTO table (a) VALUES (0)
  ON DUPLICATE KEY UPDATE a=1

আমি সন্নিবেশ বা আপডেটের আইডি চাই। আমি বিশ্বাস করি যেহেতু insert_id () কেবলমাত্র 'সন্নিবেশিত' আইডি প্রত্যাবর্তন করে আপডেট আইডি না হিসাবে এটি পেতে সাধারণত আমি দ্বিতীয় ক্যোয়ারী চালাই run

INSERT / আপডেটের কোনও উপায় আছে এবং দুটি জিজ্ঞাসা না চালিয়ে সারিটির আইডি উদ্ধার করতে পারে?


3
ভাবার চেয়ে বরং আপনি নিজেই এটি পরীক্ষা করেন না কেন? উপরের সম্পাদনাটিতে এসকিউএল কাজ করে এবং আমার পরীক্ষার মাধ্যমে সন্নিবেশ ইগনোর ব্যবহার করে বা সন্নিবেশ ইগনোর ব্যবহার করে বা প্রথমে ডুপ্লিকেট আছে কিনা তা বেছে নেওয়ার চেয়ে দ্রুততর হয়।
মাইকেল ফেনউইক

4
সতর্কতা: সমাধান প্রস্তাবিত কাজ করে, তবে সন্নিবেশ না থাকলেও স্বয়ংক্রিয়_সংশোধের মান বাড়তে থাকে। যদি সদৃশ কীটি প্রায়শই ঘটে থাকে তবে alter table tablename AUTO_INCREMENT = 0;আপনার আইডি মানগুলিতে বড় ফাঁক এড়াতে আপনি উপরের ক্যোয়ারির পরে চালাতে চাইতে পারেন ।
ফ্র্যাঙ্ক ফোর্ট 11

উত্তর:


175

এই পৃষ্ঠাটি দেখুন: https://web.archive.org/web/20150329004325/https://dev.mysql.com/doc/refman/5.0/en/insert-on-dusedate.html
পৃষ্ঠার নীচে তারা ব্যাখ্যা করে যে কীভাবে আপনি সেই মাইএসকিউএল ফাংশনে একটি এক্সপ্রেশন পাস করে আপডেটগুলির জন্য LAST_INSERT_ID অর্থবহ করতে পারেন।

মাইএসকিউএল ডকুমেন্টেশন উদাহরণ থেকে:

যদি কোনও টেবিলটিতে একটি AUTO_INCREMENT কলাম এবং INSERT থাকে ... আপডেট একটি সারি সন্নিবেশ করায়, LAST_INSERT_ID () ফাংশনটি AUTO_INCREMENT মান প্রদান করে। পরিবর্তে যদি বিবৃতিটি একটি সারি আপডেট করে, LAST_INSERT_ID () অর্থবহ নয়। তবে আপনি LAST_INSERT_ID (এক্সপ্রেস) ব্যবহার করে এটিকে ঘিরে কাজ করতে পারেন। মনে করুন যে আইডিটি হ'ল আউটপুট ক্রিমেন্ট। আপডেটের জন্য LAST_INSERT_ID () কে অর্থবহ করে তুলতে, সারিগুলি নিম্নলিখিতভাবে সন্নিবেশ করান:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

2
এই পৃষ্ঠাটি দেখার সময় কোনওরকম আমি এটি মিস করেছি। সুতরাং আপডেট অংশটি প্রদর্শিত হবে: UPDATE id = LAST_INSERT_ID (আইডি) এবং এটি দুর্দান্ত কাজ করে। ধন্যবাদ!
thekevinscott

7
বলা হয়ে থাকে যে পিএইচপি ফাংশন mysql_insert_id () উভয় ক্ষেত্রেই সঠিক মান প্রদান করে: php.net/manual/en/function.mysql-insert-id.php#59718
জয়য়ারজো

2
@ পেটারপেলার - ঠিক আছে, মাইএসকিউএল ইন্টার্নালগুলি না দেখে, সম্ভবত এটির অর্থ হ'ল এটি একটি মান উত্পন্ন করবে, তবে সেই মানটি আপনি যে ক্যোয়ারীতে চালিয়েছিলেন তার সাথে সম্পর্কিত নয়। অন্য কথায়, একটি সমস্যা যা ডিবাগ করতে ব্যথা।
জেসন

13
5.1.12 এর পরে এটি আর প্রয়োজনীয় নয় বলে মনে করা হয়, তবে আমি আজ তার ব্যতিক্রম পেয়েছি। আপনার যদি একটি স্বয়ংসোধক পিকে এবং একটি ইমেল ঠিকানা বলার জন্য একটি অনন্য কী এবং ইমেল ঠিকানার ভিত্তিতে 'অনুলিপি আপডেট' ট্রিগার থাকে তবে মনে রাখবেন যে সর্বশেষ_সিন্ট_আইডি আপডেট হওয়া সারিটির স্বতঃশক্তি মান হবে না। এটি সর্বাধিক সন্নিবেশ করা স্বতঃআগ্রহ মান হিসাবে প্রদর্শিত হচ্ছে। এটি একটি বিশাল পার্থক্য করে তোলে। আশেপাশের কাজগুলি এখানে প্রদর্শিত হিসাবে একই রকম হয়, আপডেটিং ক্যোয়ারিতে আইডি = LAST_INSERT_ID (আইডি) ব্যবহার করার জন্য।

1
5.5 এ @ এসসিডিডি-র মন্তব্য এখনও সত্য holds
e18r

37

নির্ভুলভাবে বলতে গেলে, এটি যদি মূল প্রশ্নটি হয়:

INSERT INTO table (a) VALUES (0)
 ON DUPLICATE KEY UPDATE a=1

এবং 'আইডি' হ'ল স্বয়ংক্রিয়-বর্ধিত প্রাথমিক কী এর থেকে কার্যক্ষম সমাধান হবে:

INSERT INTO table (a) VALUES (0)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), a=1

এখানে সবই রয়েছে: http://dev.mysql.com/doc/refman/5.0/en/insert-on- નકલ

যদি কোনও টেবিলটিতে একটি AUTO_INCREMENT কলাম এবং INSERT থাকে ... আপডেট একটি সারি সন্নিবেশ করায়, LAST_INSERT_ID () ফাংশনটি AUTO_INCREMENT মান প্রদান করে। পরিবর্তে যদি বিবৃতিটি একটি সারি আপডেট করে, LAST_INSERT_ID () অর্থবহ নয়। তবে আপনি LAST_INSERT_ID (এক্সপ্রেস) ব্যবহার করে এটিকে ঘিরে কাজ করতে পারেন। মনে করুন যে আইডিটি হ'ল আউটপুট ক্রিমেন্ট।


7
হ্যাঁ, আপনি যা বলেছেন তার জন্য গৃহীত উত্তরটি দেখুন। 3 বছরের পুরানো পোস্ট পুনরুদ্ধার করার দরকার নেই। যাইহোক আপনার প্রচেষ্টা জন্য ধন্যবাদ।
অভিনব প্যান্টস

1
@ টমটব আমি এই উত্তরটি পোস্ট করার একমাত্র কারণ হ'ল গৃহীত উত্তর সঠিক নয় - আপডেট করার মতো কিছু না থাকলে এটি কাজ করবে না।
আলেকসন্দর পপোভিচ

2

আপনি প্রতিস্থাপনের দিকে নজর দিতে পারেন যা রেকর্ডটি বিদ্যমান থাকলে মূলত মুছে ফেলা / isোকানো হয়। তবে এটি উপস্থিত থাকলে অটো ইনক্রিমেন্ট ক্ষেত্রটি পরিবর্তিত করবে, যা অন্যান্য ডেটার সাথে সম্পর্ক ছিন্ন করতে পারে।


1
আহা হ্যাঁ - আমি এমন কিছু সন্ধান করছি যা পূর্ববর্তী আইডি থেকে মুক্তি পাবে না
থেকেভিনস্কট

এটি বিপজ্জনকও হতে পারে কারণ এটি অন্য কোনও সম্পর্কিত ডেটা (সীমাবদ্ধতার দ্বারা) মোছার কারণও হতে পারে।
সার্জ

2

আমি জানি না যে আপনার মাইএসকিউএল এর সংস্করণটি কী তবে InnoDB এর সাথে অটোয়েন্টের সাথে বাগ ছিল g

5.1.20 এ বাগ এবং 5.1.23 http://bugs.mysql.com/bug.php?id=27405 এ সংশোধন করা হয়েছে

5.1.31 এ বাগ এবং 5.1.33 http://bugs.mysql.com/bug.php?id=42714 এ সংশোধন করা হয়েছে


1

আমি একটি সমস্যার মুখোমুখি হয়েছি, যখন ডুপ্লিকেট কী আপডেটের সময় আইডি = LAST_INSERT_ID (আইডি) প্রাইমারী কীটি 1 দিয়ে বাড়িয়ে দেই। সুতরাং সেশনের পরবর্তী ইনপুটটির আইডি 2 দ্বারা বাড়ানো হবে


0

এটি লক্ষণীয়, এবং এটি সুস্পষ্ট হতে পারে (তবে আমি এখানে এটি স্পষ্টতার জন্য বলব), যে প্রতিস্থাপনটি আপনার নতুন ডেটা REোকানোর আগে বিদ্যমান মিলের সারিটি দূরে সরিয়ে দেবে। অনুলিপি কী আপডেটের পরে কেবলমাত্র আপনার নির্দিষ্ট করা কলামগুলি আপডেট করা হবে এবং সারিটি সংরক্ষণ করা হবে।

ম্যানুয়াল থেকে :

প্রতিস্থাপন হ'ল INSERT এর মতো কাজ করে, ব্যতীত যদি টেবিলের কোনও পুরনো সারিটি PRIARY KEY বা UNIQUE সূচকের জন্য একটি নতুন সারিটির সমান মান থাকে তবে নতুন সারিটি সন্নিবেশ করার আগে পুরানো সারিটি মুছে ফেলা হয়।


0

বিদ্যমান সমাধানগুলি যদি আপনি স্বতঃসংশোধন ব্যবহার করেন তবে কাজ করে। আমার এমন একটি পরিস্থিতি রয়েছে যেখানে ব্যবহারকারী একটি উপসর্গটি সংজ্ঞায়িত করতে পারে এবং এটি 3000 এ ক্রমটি পুনরায় আরম্ভ করতে হবে this এই বিবিধ উপসর্গের কারণে আমি স্বতঃআগ্রহ ব্যবহার করতে পারি না, যা সর্বশেষ-সন্নিবেশ_দকে সন্নিবেশের জন্য খালি করে দেয়। আমি নিম্নলিখিতগুলির সাথে এটি সমাধান করেছি:

INSERT INTO seq_table (prefix, id) VALUES ('$user_prefix', LAST_INSERT_ID(3000)) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id + 1);
SELECT LAST_INSERT_ID();

উপসর্গটি উপস্থিত থাকলে, এটি এটিকে বাড়িয়ে দেবে এবং সর্বশেষ_সাইন্ট_আইডি স্থাপন করবে। উপসর্গটি উপস্থিত না থাকলে এটি 3000 মান সহ উপসর্গটি সন্নিবেশ করবে এবং 3000 সহ সর্বশেষ_সাইন্ট_আইডিকে পপুলেট করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.