অনুলিপি কী আপডেট সন্নিবেশ হিসাবে একই


158

আমি আশেপাশে অনুসন্ধান করেছি কিন্তু এটি সম্ভব কিনা তা খুঁজে পেলাম না।

আমি এই মাইএসকিউএল কোয়েরি করেছি:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8)

ফিল্ড আইডির একটি "অনন্য সূচক" রয়েছে, সুতরাং সেগুলির মধ্যে দুটি থাকতে পারে না। এখন যদি একই আইডিটি ইতিমধ্যে ডাটাবেসে উপস্থিত থাকে তবে আমি এটি আপডেট করতে চাই। তবে আমাকে কি সত্যিই এই সমস্ত ক্ষেত্রটি আবার নির্দিষ্ট করতে হবে, যেমন:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY UPDATE a=2,b=3,c=4,d=5,e=6,f=7,g=8

বা:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY UPDATE a=VALUES(a),b=VALUES(b),c=VALUES(c),d=VALUES(d),e=VALUES(e),f=VALUES(f),g=VALUES(g)

আমি ইতিমধ্যে সন্নিবেশে সমস্ত নির্দিষ্ট করেছি ...

একটি অতিরিক্ত নোট, আমি আইডিটি পেতে চারপাশের কাজটি ব্যবহার করতে চাই!

id=LAST_INSERT_ID(id)

আমি আশা করি যে কেউ সবচেয়ে কার্যকর উপায়টি আমাকে বলতে পারেন।


9
প্রতিটি কলামকে বিশ্রাম দেওয়ার পদ্ধতি আফাইক, a=VALUES(a), b=VALUES(b), ...আপনার যাবার দরকার। আমি আমার সমস্ত INSERT ON DUPLICATE KEY UPDATEবক্তব্যের জন্য এটিই করি ।
ভালডগ 21

4
কেবল স্পষ্ট করে বলার জন্য, যতক্ষণ আপনি এখানে প্রশ্নের উত্তর দেওয়া হচ্ছে বুঝতে পারছেন ততক্ষণ এখানে বর্ণিত সমস্ত কিছুই সঠিক: আপনি কি প্রতিটি কলামটি আপডেট করতে চান? হ্যাঁ, আপনি যদি 25-কলামের সারণীতে 8 টি কলাম সন্নিবেশ করতে বা আপডেট করতে চান তবে আপনাকে অবশ্যই 8 টি কলাম দুটি বার লিখতে হবে - একবার সন্নিবেশ অংশে এবং একবার আপডেট অংশে। (আপনি আপডেটের অংশে প্রাথমিক কীটি এড়িয়ে যেতে পারেন তবে একটি "এ = 1, বি = 2, সি = 3" স্ট্রিংটি পূর্বে ফর্ম্যাট করা এবং এটি দু'বার এম্বেড করা সহজ iest) তবে আপনাকে বাকি 17 টি কলাম পুনরায় আরম্ভ করতে হবে না আপনি পরিবর্তন করতে চান না। যদি এটি আপডেট হয় তবে তারা তাদের বিদ্যমান মানগুলি রাখবে।
টিম্বললাইন

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

1
পরীক্ষা করে দেখুন stackoverflow.com/questions/2472229/... , আমি মনে করি সেখানে কি আপনি যা খুঁজছেন
Chococroc

উত্তর:


82

UPDATEবিবৃতি, যাতে পুরোনো ক্ষেত্র নতুন মান আপডেট করা যাবে দেওয়া হয়। যদি আপনার পুরানো মানগুলি আপনার নতুন হিসাবে একই হয় তবে কেন এটি কোনও ক্ষেত্রে আপডেট করার প্রয়োজন হবে?

যেমন যেমন আপনার কলাম যদি aকরতে gইতিমধ্যে হিসাবে সেট করা 2থেকে 8; এটি পুনরায় আপডেট করার প্রয়োজন হবে না।

বিকল্পভাবে, আপনি ব্যবহার করতে পারেন:

INSERT INTO table (id,a,b,c,d,e,f,g)
VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY
    UPDATE a=a, b=b, c=c, d=d, e=e, f=f, g=g;

পেতে idথেকেLAST_INSERT_ID ; আপনি একই জন্য ব্যবহার করছেন ব্যাকএন্ড অ্যাপটি নির্দিষ্ট করতে হবে।

লুয়াএসকিউএল-এর জন্য, conn:getlastautoid()মানটি পাওয়া যায়।


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

1
"একটি অতিরিক্ত নোট, আমিও আইডি পেতে চারপাশের কাজটি ব্যবহার করতে চাই!"
আগামেমনস

1
@ ট্রেডসিন, যতদূর আমি এটি বলতে পারি কেবল সিনট্যাকটিক চিনি। ব্যক্তিগতভাবে, আমি কখনই a = VALUES (a), b = VALUES (b) ইত্যাদি ব্যবহার করে কাউকে দেখতে পাইনি সম্ভবত আপনি কলামটিতে একাধিক মান নির্ধারণ করতে পারবেন? নিশ্চিত না কেন আপনি কেবল আগেই ডেটাটি সংযুক্ত করবেন না।
ডাকপঞ্চটি

54
টেবিল যদি tblইতিমধ্যে সারি (1,10) আছে তারপর: INSERT INTO tbl(id, a) VALUES(1,2) ON DUPLICATE KEY UPDATE a=VALUES(a)একটি = সেট হবে 2 । যখন INSERT INTO tbl(id, a) VALUES(1,2) ON DUPLICATE KEY UPDATE a=aএকটি = 10
Bùi Việt Thành

2
সব উচ্ছ্বাস কেন? এটা কাজ করে না. @ বিআই ভাইট থান উল্লেখ করেছেন যে a=aআপডেটগুলি কিছুই ব্যবহার করে না। (মূল প্রশ্নের প্রশ্নগুলি আসলে কোনও কিছু আপডেট করে না, তবে একটি আপডেট মনে হয় ওপি কী লক্ষ্য করে))
রজার ডিউক

41

এসকিউএল-এর একটি মাইএসকিউএল নির্দিষ্ট এক্সটেনশন রয়েছে যা আপনি যা চান তা হতে পারে - REPLACE INTO

তবে এটি 'অনুলিপি আপডেটের মতো' মতো একইভাবে কাজ করে না

  1. এটি পুরানো সারিটি মুছে ফেলা হয় যা নতুন সারিটির সাথে সংঘর্ষ হয় এবং তারপরে নতুন সারি সন্নিবেশ করে। এতক্ষণ আপনার টেবিলে কোনও প্রাথমিক কী নেই যা ভাল হবে, তবে আপনি যদি তা করেন, তবে অন্য কোনও টেবিল যদি সেই প্রাথমিক কীটি উল্লেখ করে

  2. আপনি পুরানো সারিগুলিতে মানগুলি উল্লেখ করতে পারবেন না যাতে আপনি এর সমতুল্য না করতে পারেন

    INSERT INTO mytable (id, a, b, c) values ( 1, 2, 3, 4) 
    ON DUPLICATE KEY UPDATE
    id=1, a=2, b=3, c=c + 1;

আইডিটি পেতে আমি চারপাশের কাজটি ব্যবহার করতে চাই!

এটির কাজ করা উচিত - আপনার প্রাথমিক কীটি স্বয়ংক্রিয়ভাবে বাড়ানো হয় ততক্ষণ সর্বশেষ_সামগ্রী_আইডি () এর সঠিক মান হওয়া উচিত।

তবে আমি যেমন বলেছি, আপনি যদি অন্য টেবিলে সেই প্রাথমিক কীটি ব্যবহার করেন তবে REPLACE INTOসম্ভবত এটি আপনার কাছে গ্রহণযোগ্য হবে না, কারণ এটি অনন্য কীটির মাধ্যমে সংঘর্ষের পুরানো সারিটি মুছে ফেলে।

আপনি লিখে দিয়ে কিছু টাইপ কমিয়ে আনার আগে অন্য কেউ পরামর্শ দিয়েছেন :

INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE `a`=VALUES(`a`), `b`=VALUES(`b`), `c`=VALUES(`c`);

সুতরাং, আমি কোনও replace intoপ্রশ্নের আগে প্রাথমিক কী দিয়ে আটকাতে পারি না ?
রায়

না - এই সারিটি মুছে ফেলা হয়েছে এবং একটি নতুন সারি তৈরি করা হয়েছে, এতে একটি নতুন প্রাথমিক কী থাকবে।
ড্যানাক

এটি কি বড় ডেটাসেটগুলিতে প্রক্রিয়াটি ধীর করবে এবং 100 কে বা আরও সারি সহ সিএসভি'র আমদানি পছন্দ করবে?
মুহাম্মদ ওমর আসলাম

24

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


9
এটি ভুল এবং গ্রহণযোগ্য উত্তর হওয়া উচিত নয়। @ ড্যান্যাকের উত্তর সঠিক উত্তর।
ওয়েইন ওয়ার্মম্যান

2
আপনার @WayneWorkman প্রশ্নটি পুনরায় পড়তে হবে, এটি সঠিক উত্তর।
রায়

24

আপনার সমস্যার সমাধান এখানে দেওয়া হল:

আমি আপনার মত সমস্যা সমাধান করার চেষ্টা করেছি এবং আমি সহজ দিক থেকে পরীক্ষা করার পরামর্শ দিতে চাই।

এই পদক্ষেপগুলি অনুসরণ করুন: সহজ সমাধান থেকে শিখুন।

পদক্ষেপ 1: এই এসকিউএল কোয়েরি ব্যবহার করে একটি টেবিল স্কিমা তৈরি করুন :

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(32) NOT NULL,
  `status` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `no_duplicate` (`username`,`password`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

ডেটা সহ একটি সারণী <কোড> ব্যবহারকারী </ কোড>

পদক্ষেপ 2: নিম্নলিখিত এসকিউএল কোয়েরি ব্যবহার করে সদৃশ ডেটা প্রতিরোধ করতে দুটি কলামের একটি সূচক তৈরি করুন :

ALTER TABLE `user` ADD INDEX no_duplicate (`username`, `password`);

বা, জিইউআই থেকে নীচে দুটি কলামের একটি সূচক তৈরি করুন : জিইউআই থেকে সূচক তৈরি করুন সূচি তৈরি করতে কলাম নির্বাচন করুন সারণি <কোড> ব্যবহারকারী </ কোড> এর সূচি

পদক্ষেপ 3: উপস্থিত থাকলে আপডেট করুন, নিম্নলিখিত কোয়েরিগুলি ব্যবহার না করে sertোকান:

INSERT INTO `user`(`username`, `password`) VALUES ('ersks','Nepal') ON DUPLICATE KEY UPDATE `username`='master',`password`='Nepal';

INSERT INTO `user`(`username`, `password`) VALUES ('master','Nepal') ON DUPLICATE KEY UPDATE `username`='ersks',`password`='Nepal';

উপরে কোয়েরি চালানোর পরে টেবিল <কোড> ব্যবহারকারী </ কোড>


1
এই ওয়াকথ্রু জন্য আপনাকে ধন্যবাদ - আমাকে বুঝতে, উচ্চ প্রশংসা, ধন্যবাদ!
মাইকেল নীলসন

এফওয়াইআই পাসওয়ার্ডগুলি সরল পাঠ্যে সংরক্ষণ করা একটি ভয়ানক ধারণা, যেমন ডাটাবেস স্তরে সদৃশ পাসওয়ার্ডগুলি প্রতিরোধ করার চেষ্টা করা হচ্ছে।
অরেঞ্জডগ

10

আপনার এসকিউএল কোয়েরি প্রস্তুত করতে আপনি যদি কোনও স্ক্রিপ্টিং ভাষা ব্যবহার করতে সক্ষম হন তবে আপনি ক্ষেত্রটি = মান জোড় ব্যবহার করে পুনরায় ব্যবহার করতে পারেন SET পরিবর্তে করতে পারেন (a,b,c) VALUES(a,b,c)

পিএইচপি সহ একটি উদাহরণ:

$pairs = "a=$a,b=$b,c=$c";
$query = "INSERT INTO $table SET $pairs ON DUPLICATE KEY UPDATE $pairs";

উদাহরণ সারণী:

CREATE TABLE IF NOT EXISTS `tester` (
  `a` int(11) NOT NULL,
  `b` varchar(50) NOT NULL,
  `c` text NOT NULL,
  UNIQUE KEY `a` (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

4
আপনার মানগুলি থেকে বাঁচতে হবে বা আপনার মান সহ একটি প্রস্তুত বিবৃতি কার্যকর করা উচিত।
চিনোটো ভোকরো

1
@ চিনোটোভোক্রো - আমি সম্মত এটি কেবল একটি "আপনি কীভাবে পারেন" উপস্থাপন করছে এবং উদাহরণে কোনও কোয়েরি ফাংশন ব্যবহার করছে না।
ক্রিস

1
কীগুলির অ্যারে এবং মানগুলির একটি অ্যারে উল্লেখ করার জন্য এটি একটি ভাল বিকল্প। ধন্যবাদ।
মার্ক কার্পেন্টার জুনিয়র

5

ব্যবহার করে আপনি বিবেচনা করতে পারেন REPLACE INTOসিনট্যাক্স কিন্তু ডুপ্লিকেট প্রাথমিক পরে, সতর্ক করা / অনন্য কী, এটা মুছে ফেলে সারি এবং টিপে একটি নতুন এক।

আপনাকে সমস্ত ক্ষেত্র পুনরায় নির্দিষ্ট করতে হবে না। তবে আপনার সম্ভাব্য পারফরম্যান্স হ্রাস বিবেচনা করা উচিত (আপনার টেবিল ডিজাইনের উপর নির্ভর করে)।

আদেশ সহকারে:

  • আপনার যদি স্বয়ংক্রিয় ক্রিমেন্ট প্রাথমিক কী থাকে তবে এটি একটি নতুন দেওয়া হবে
  • সূচকগুলি সম্ভবত আপডেট করার প্রয়োজন হবে

অন্য কোনও সারণীর জন্য সূচকটি যদি বিদেশী কী হয় তবে সীমাবদ্ধতা লঙ্ঘন রয়েছে it's
ব্যবহারকারী 3290180

4

আমি জানি যে দেরি হয়ে গেছে, তবে আমি আশা করি যে কেউ এই উত্তরটির জন্য সহায়তা করবে

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

আপনি নীচের টিউটোরিয়াল এখানে পড়তে পারেন:

https://mariadb.com/kb/en/library/insert-on-duplicate-key-update/

http://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/


ভাল উত্তর. তবে নতুন সারিগুলিকে উল্লেখ করতে ভ্যালু () এর ব্যবহারটি মাইএসকিউএল 8.0.20 হিসাবে অবচিত করা হয়েছে । এই লিঙ্কটিতে বিশদভাবে জানানো নতুন পদ্ধতির সারিটির জন্য একটি উপনাম ব্যবহার করা। এই উদাহরণে, উপনামটি হ'ল new:INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new ON DUPLICATE KEY UPDATE c = new.a+new.b;
ব্যবহারকারী 69747373

@ ব্যবহারকারীর 697473 আমি ত্রুটিটি পাচ্ছি: "আপনার এসকিউএল সিনট্যাক্সে আপনার একটি ত্রুটি রয়েছে; ডান সিটেক্সের জন্য 'মারিয়্যাডিবি সার্ভার সংস্করণের সাথে সামঞ্জস্যপূর্ণ ম্যানুয়ালটি পরীক্ষা করুন' নতুন নতুন সংস্করণ হিসাবে নতুন হিসাবে আপডেট করুন a = new.a '" , এবং আমার কোয়েরিটি কাজ করছিল (ডুপ্লিকেট কীগুলি উপস্থিত হওয়া ব্যতীত, স্পষ্টতই) আমি এই ধারাটি প্রয়োগ করার আগে। কোন ধারনা?
অ্যারোন

@ অ্যারন - দুঃখিত, দুর্দান্ত ধারণা নেই। মাইএসকিউএল 8.0.20 সবেমাত্র এপ্রিলের শেষে প্রকাশিত হয়েছিল; সম্ভবত মারিয়াডবি এখনও ধরেনি। এটি আপনাকে ত্রুটি কেন দিচ্ছে তা ব্যাখ্যা করতে পারে।
ব্যবহারকারী 697473

@ ব্যবহারকারী 697473 হ্যাঁ আমি আসলে আসল উত্তরে a = VALUES (a) পদ্ধতিটি চেষ্টা করেছি এবং এটি কার্যকর হয়েছে, যাইহোক ধন্যবাদ।
আরোন

-7

আপনি যেমন ক্ষেত্রে সন্নিবেশ উপেক্ষা ব্যবহার করতে পারেন, এটি অনুলিপি রেকর্ড INSERT IGNORE পেলে তা উপেক্ষা করবে ...; - অনুলিপি কী ছাড়াই


আমি উপস্থিত না থাকলে এটি সন্নিবেশ করতে চেয়েছিলাম, অন্যথায় এটি আপডেট করুন। এড়ানো হবে না।
রায়

কেন আপনি তা আপডেট করতে আপনি, পূর্ববর্তী / একই মান আপডেট যদি চান তাহলে তার একটি নতুন মান তারপর, এটা তার ঠিক আছে, যদি না সন্নিবেশ জন্য কাজ উপেক্ষা করা
pitu

2
সম্ভবত মানগুলি পরিবর্তিত হতে পারে এবং তিনি উপস্থিত না থাকলে তিনি একটি রেকর্ড তৈরি করতে চান, তবে বিদ্যমান রেকর্ডটি আপডেট করুন যদি এটি পরিবর্তন করে (অ্যাপ্লিকেশনগুলিতে) একটি বৃত্তাকার ট্রিপের ওভারহেড না করে আবার ডাটাবেসে ফিরে আসে আবার।
মপসাইড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.