একই মাইএসকিউএল টেবিলে নকল / অনুলিপি রেকর্ডগুলি


87

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

আমার এই প্রশ্নটি রয়েছে:

INSERT INTO invoices
    SELECT * FROM invoices AS iv WHERE iv.ID=XXXXX
    ON DUPLICATE KEY UPDATE ID = (SELECT MAX(ID)+1 FROM invoices)

সমস্যাটি হ'ল এটি কেবল IDসারিটি অনুলিপি করার পরিবর্তে সারিটির পরিবর্তনগুলি পরিবর্তন করে । কেহ এই ঠিক কিভাবে কি জানে ?

// সম্পাদনা: আমি সমস্ত ক্ষেত্রের নাম টাইপ না করে এটি করতে চাই কারণ ক্ষেত্রের নাম সময়ের সাথে সাথে পরিবর্তন হতে পারে।

উত্তর:


137

আমি সাধারণত যেভাবে ঘুরে দেখি তা অস্থায়ী টেবিলটি ব্যবহার করা। এটি সম্ভবত গণনামূলকভাবে দক্ষ নয় তবে এটি ঠিক কাজ করছে বলে মনে হচ্ছে! এখানে আমি সম্পূর্ণরূপে রেকর্ড 99 নকল করছি, রেকর্ড 100 তৈরি করছি।

CREATE TEMPORARY TABLE tmp SELECT * FROM invoices WHERE id = 99;

UPDATE tmp SET id=100 WHERE id = 99;

INSERT INTO invoices SELECT * FROM tmp WHERE id = 100;

আশা করি এটি আপনার পক্ষে ঠিক কাজ করে!


আমি এটি পছন্দ করি, বিষয়গুলির দিকে নজর রাখার জন্য মাঝখানে এক ধাপ
সানডাউনী

4
আপনি যদি একটি একক রেকর্ড অনুলিপি করেন তবে আপডেট এবং সন্নিবেশ উভয় ক্ষেত্রেই আপনি সেখানে ফেলে দিতে পারেন। তারপরে আপনি মাইএসকিএল কনসোলে কেবল দু'বার চাপ দিতে পারেন যা ইতিহাসের শেষ ক্রিয়াকলাপের পরবর্তী অংশটি আনবে, আইডিটি আপডেটে পরিবর্তন করুন যা শেষে সুবিধাজনক, এন্টার টিপুন, টিপুন, কোনও পরিবর্তন না করে আবার প্রবেশ করুন, তারপরে পুনরাবৃত্তি করুন একাধিক অনুলিপি জন্য পদ্ধতি। অনেক দ্রুত.
ক্রিশ্চিয়ান ভ্রাবী

4
যদি আইডি 100 ইতিমধ্যে থাকে তখন কী হয়। দ্বিতীয়ত, যদি আপনি আপনার নতুন সারির জন্য কোনও নতুন আইডি চয়ন করেন এবং অপারেশনের সময় অন্য কেউ একটি নতুন সারি andোকান এবং তারপরে আপনার আইডি এবং সদ্য sertedোকানো আইডি একই হবে। এই কোডটিতে এই বোতল ঘাড় আছে।
nbhatti2001

6
আপনি নুল ব্যবহার করতে পারেন:CREATE TEMPORARY TABLE tmp SELECT bla FROM invoices WHERE bla; UPDATE tmp SET id=NULL; INSERT INTO invoices SELECT * FROM tmp;
টোবিয়াস বেইভিং

4
কারণ আমি যে @TobiasBeuving একটি কপি-পেস্ট ত্রুটি বার্তাটি আছে NOT NULLসেট id। আমি কেবল ভাবছিলাম যে এই মামলার জন্য আপনার কাছে পরামর্শ আছে কিনা। এটি কি খারাপ অভ্যাস হিসাবে বিবেচিত?
মার্সেল

84

অ্যালেক্সের উত্তরের একাধিক ক্লায়েন্ট পরিবেশে কিছু যত্নের প্রয়োজন (যেমন লকিং বা লেনদেন)।

AUTO IDক্ষেত্রটিকে টেবিলের প্রথম হিসাবে ধরে নেওয়া (একটি সাধারণ ক্ষেত্রে), আমরা অন্তর্ভুক্ত লেনদেনের ব্যবহার করতে পারি।

    টেম্পোরারি টেবিল তৈরি করুন TMP নির্বাচন করুন ইনভয়েস থেকে যেখানে ...;
    টেবিল টেম্প ড্রপ আইডি বিকল্প; # ড্রপ স্বতঃআগ্রহ ক্ষেত্র
    # আপডেট আপডেট টেম্প সেট ...; # অন্য অনন্য কীগুলি পরিবর্তন করার প্রয়োজন মাত্র
    অন্তর্ভুক্ত ইনভয়েসগুলি নির্বাচন করুন 0, tmp। * টিএমপি থেকে;
    ট্রপ টেবিল ড্রপ;

মাইএসকিউএল ডক্স থেকে:

স্বয়ংক্রিয় ক্রিমেন্ট ব্যবহার: আপনি ক্রম সংখ্যা তৈরি করতে কলামে স্পষ্টভাবে NULL বা 0 নির্ধারণ করতে পারেন।


এটি আমার কাছে 0 আইডি সহ রেকর্ডটি রাখে, যদিও আমার কাছে একটি স্বতঃপরিচয় ক্ষেত্র রয়েছে। এটিকে নালিতে পরিবর্তন করা কাজ করে, তাই আমি আপনাকে 0 এর পরিবর্তে নাল ব্যবহার করার জন্য কোডটি পরিবর্তন করার পরামর্শ দিই My আমি মাইএসকিউএল 5.5.35 (উবুন্টু) এ আছি।
টাইলার কলিয়ার

@ টাইলারকলার: NULLবা 0উভয়ই গ্রহণযোগ্য। আপনি কি পুনরায় উত্পাদন করে সমস্যার স্ক্রিন শট পোস্ট করতে এবং এটি এখানে ভাগ করতে পারেন।
রবীন্দ্র রেড্ডি

আমার মস্তিষ্কে 4 টি লাইনটি নীটো সাবকিউরিটি বোঝার চেষ্টা করে আঘাত করা হতে পারে সম্ভবত এই ব্যাখ্যাটি সহায়তা করে: গন্তব্য সারণীতে invoicesএকটি স্বতঃসংশ্লিষ্ট IDক্ষেত্র রয়েছে । উত্স টেবিল tmpনা। সন্নিবেশকালে প্রয়োজনীয় 1: 1 পারস্পরিক সম্পর্ক পেতে, আপনি 0নির্বাচনের প্রথম ক্ষেত্র হিসাবে একটি নির্দিষ্ট করুন যা গন্তব্য টেবিলের আউটপুট অবধি ক্ষেত্র is tmp.*নির্বাচন উৎস টেবিল থেকে সব ক্ষেত্র tmp। পারফেক্ট! আপনার এখন আপনার 1: 1 এর সম্পর্ক রয়েছে। দুর্দান্ত উত্তর @ টিম।
এলবোলোস্টারস্টারস্ট্যান্ড

@ রবীন্দ্র রেডি নুল এবং 0 এক নয় - 0 এর রেকর্ড-আইডি পাওয়া সম্ভব - এই ধরণের জিনিসটির জন্য NULL ব্যবহার করুন
টোবিয়াস বেইভিং

@TobiasBeuving : আমি যে ভাল সচেতন NULLএবং0 একই নয়। বর্তমান প্রসঙ্গটি AUTO_INCREMENTবৈশিষ্ট্যে রয়েছে। আপনি এই জাতীয় ক্ষেত্রগুলিতে একটি 0বা একটি NULLমান সন্নিবেশ করতে পারবেন না । তবে আপনি যখন তাদের এই জাতীয় ক্ষেত্রের ইনপুট হিসাবে ব্যবহার করেন, পরবর্তী ক্রমিক মানটি সেই ক্ষেত্রের স্বয়ংক্রিয়ভাবে ম্যাটিক্যালি বরাদ্দ করা হবে । এবং তাই আমার মন্তব্য। এসকিউএল ফিডল-এর প্রমাণ: sqlfiddle.com/#!9/d619f/1
রবীন্দ্র রেড্ডি

12

আপনি নিশ্চিতভাবে জানেন, যে দ্বৈত কী টি ট্রিগার করবে, সুতরাং আপনি আগেই MAX (ID) +1 নির্বাচন করতে পারেন:

INSERT INTO invoices SELECT MAX(ID)+1, ... other fields ... FROM invoices AS iv WHERE iv.ID=XXXXX 

4
হ্যাঁ, তবে আমি অন্য সমস্ত ক্ষেত্রগুলি টাইপ করতে চাই না (কমপক্ষে 20 টি রয়েছে এবং এটি সময়ের সাথে সাথে পরিবর্তন হতে পারে)। আমি টেবিলস্ট্রাক্টারে প্রতিবার কোড পরিবর্তন করতে চাই না।
অঙ্কগুলি

তোমাকে করতে হবে. আপনি ক্ষেত্রের তালিকা থেকে এসকিউএল বিবৃতি উত্পন্ন করে এমন একটি স্ক্রিপ্ট আরও ভাল তৈরি করুন। এটা তুচ্ছ।
ইঙ্গো

কেবলমাত্র অন্য বিকল্পটি একটি সন্নিবেশ ট্রিগার (যদি মাইএসকিএল এটি সমর্থন করে) ব্যবহার করে।
এঙ্গো

11

আপনার পদ্ধতিটি ভাল তবে সমস্যাটি হল আপনি ক্ষেত্রের নাম তালিকাভুক্ত করার পরিবর্তে "*" ব্যবহার করুন। যদি আপনি প্রাথমিক কী বাদে সমস্ত কলামের নাম রাখেন তবে আপনার স্ক্রিপ্ট এক বা একাধিক রেকর্ডে কব্জির মতো কাজ করবে।

INSERT INTO invoices (iv.field_name, iv.field_name,iv.field_name ) SELECT iv.field_name, iv.field_name,iv.field_name FROM invoices AS iv WHERE iv.ID=XXXXX


তবে এর অর্থ হ'ল যে কোনও ক্ষেত্র যোগ করা বা টেবিল থেকে বাদ দেওয়ার সাথে সাথে আপনাকে কোডটি পরিবর্তন করতে হবে, যা আমি ব্যক্তিগতভাবে একটি মেজর নং-নম্বর পেয়েছি। (সর্বদা নয়, তবে প্রায়শই যথেষ্ট))
রোমের

10

একটি দেরী উত্তর আমি জানি, তবে এটি এখনও একটি সাধারণ প্রশ্ন, আমি অন্য একটি উত্তর যুক্ত করতে চাই যা এটি কেবলমাত্র একটি একক লাইন insert intoবিবৃতি ব্যবহার করে আমার জন্য কাজ করেছিল এবং আমি মনে করি যে এটি কোনও নতুন টেবিল তৈরি না করেই সোজা হয়ে গেছে (যেহেতু এটি পারে CREATE TEMPORARY TABLEঅনুমতি সহ একটি সমস্যা হতে পারে ):

INSERT INTO invoices (col_1, col_2, col_3, ... etc)
  SELECT
    t.col_1,
    t.col_2,
    t.col_3,
    ...
    t.updated_date,
  FROM invoices t;

সমাধান AUTO_INCREMENTআইডি কলামের জন্য কাজ করছে , অন্যথায়, আপনি IDবিবৃতিতে কলামও যুক্ত করতে পারেন :

INSERT INTO invoices (ID, col_1, col_2, col_3, ... etc)
  SELECT
    MAX(ID)+1,
    t.col_1,
    t.col_2,
    t.col_3,
    ... etc ,
  FROM invoices t;

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


4
অনুলিপি করার সময় কিছু ক্ষেত্র পরিবর্তন করার জন্য এটিও একটি ভাল ভিত্তি। আমি INSERT into wp_options SELECT NULL, 'theme_mods_twopress', option_value, autoload FROM wp_options where option_name = 'theme_mods_onepress';এন্ট্রি ( AUTO_INCREMENT NULLউপরে থেকে কৌশল) এবং option_nameক্ষেত্রটিও বাড়ানোর সময় অনুলিপি করতাম ।
মার্সেল ওয়াল্ডভোগেল

হ্যাঁ .. আমার জন্য ভাল ধারণা। ধন্যবাদ!!
রাগু

সেরা সমাধান
এরলন চার্লস

3

আপনি যদি রেকর্ডের পুরো সেটটিকে নকল করতে চান তবে এটি যথাযথ করার জন্য আমি কেবল অ্যালেক্সের দুর্দান্ত উত্তরটি প্রসারিত করতে চেয়েছিলাম:

SET @x=7;
CREATE TEMPORARY TABLE tmp SELECT * FROM invoices;
UPDATE tmp SET id=id+@x;
INSERT INTO invoices SELECT * FROM tmp;

আমাকে কেবল এটি করতে হয়েছিল এবং অ্যালেক্সের উত্তরটি খুঁজে পেয়েছিলাম একটি নিখুঁত জাম্পিং অফ পয়েন্ট! অবশ্যই, আপনি টেবিলের সর্বাধিক সারি সংখ্যায় @x নির্ধারণ করতে হবে (আমি নিশ্চিত যে আপনি এটি কোনও ক্যোয়ারির সাহায্যে গ্রহণ করতে পারেন)। এটি কেবলমাত্র এই খুব নির্দিষ্ট পরিস্থিতিতেই কার্যকর, সুতরাং যখন আপনি সমস্ত সারিটির সদৃশ করতে চান না তখন এটি ব্যবহারে সতর্ক হন। প্রয়োজনীয় হিসাবে গণিত সামঞ্জস্য করুন।


2

আমার একই রকম সমস্যা রয়েছে এবং আমি এটি করছি:

insert into Preguntas  (`EncuestaID`, `Tipo` , `Seccion` , `RespuestaID` , `Texto` )  select '23', `Tipo`, `Seccion`, `RespuestaID`, `Texto` from Preguntas where `EncuestaID`= 18

প্রিগ্যান্টাস হয়েছে:

CREATE TABLE IF NOT EXISTS `Preguntas` (
  `ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `EncuestaID` int(11) DEFAULT NULL,
  `Tipo` char(5) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Seccion` int(11) DEFAULT NULL,
  `RespuestaID` bigint(11) DEFAULT NULL,
  `Texto` text COLLATE utf8_unicode_ci ,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=522 ;

সুতরাং, IDস্বয়ংক্রিয়ভাবে বৃদ্ধি পেয়েছে এবং আমি এর জন্য একটি স্থির মান ('23') ব্যবহার করছি EncuestaID


দুঃখিত, আমি ঠিক বুঝতে পেরেছি আপনি কলামের নামটি ব্যবহার করতে চান না, সুতরাং এটি প্রযোজ্য নয়
অ্যালেক্স অ্যাঞ্জেলিকো

1

আমারও এটি দরকার ছিল; আমার সমাধানটি এসকিউএল (একটি সন্নিবেশ তৈরি করে) হিসাবে কাঙ্ক্ষিত রেকর্ডটি রফতানি করতে এসকিউএলওয়াইজি (ফ্রি সংস্করণ) ব্যবহার করা ছিল।

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

এটি আমাকে একটি রেকর্ড সরবরাহ করে যা আমি লাইভ সিস্টেমে পরীক্ষার উদ্দেশ্যে ব্যবহার করতে পারি।

টেবিলটি প্রতিদিন নতুন করে লেখা হয় বলে আমার কাছে এখন পুনরায় ব্যবহারের জন্য এই সন্নিবেশ রয়েছে।


0

সামান্য প্রকরণ, প্রাথমিক কী ক্ষেত্র ("বর্ণ") টি বাতিল করতে মূল পার্থক্য হ'ল এটি একটি সতর্কতা তৈরি করে তবে কাজ করে। প্রাথমিক কীটি নালায় সেট করে, শেষ বিবৃতিতে রেকর্ডটি সন্নিবেশ করার সময় স্বতঃবৃদ্ধি কাজ করে।

এই কোডটি পূর্ববর্তী প্রচেষ্টাগুলিও পরিষ্কার করে এবং সমস্যা ছাড়াই একাধিকবার চালানো যেতে পারে:

DELETE FROM `tbl` WHERE varname="primary key value for new record";
DROP TABLE tmp;
CREATE TEMPORARY TABLE tmp SELECT * FROM `tbl` WHERE varname="primary key value for old record";
UPDATE tmp SET varname=NULL;
INSERT INTO `tbl` SELECT * FROM tmp;

0

আপনি আইডি ক্ষেত্রটিকে একটি বড় বা তার চেয়ে বড় প্রয়োজনে পরিবর্তন করতে অস্থায়ীভাবে সারণীটি পরিবর্তন করতে পারেন, তারপরে সেই অস্থায়ী সারণীতে আইডি 0 তে সেট করুন। এর পরে এটিকে আবার মূল টেবিলের সাথে যুক্ত করুন এবং NUL স্বয়ংক্রিয় বৃদ্ধি বৃদ্ধি করবে।

CREATE TEMPORARY TABLE tmptable SELECT * FROM x WHERE (id='123');
ALTER TABLE tmptable CHANGE id id bigint;
UPDATE tmptable SET id = NULL;
INSERT INTO x SELECT * FROM tmptable;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.