কীভাবে মাইএসকিউএলে 'উপস্থিত না থাকলে সন্নিবেশ' করবেন?


838

আমি গুগলিং দিয়ে শুরু করেছিলাম এবং এই নিবন্ধটি পেয়েছি যা মিটেক্স টেবিল সম্পর্কে আলোচনা করে।

আমার 14 মিলিয়ন ডলার রেকর্ড সহ একটি টেবিল রয়েছে। যদি আমি একই ফর্ম্যাটে আরও ডেটা যুক্ত করতে চাই, তবে এমন কোনও উপায় আছে যা আমি প্রবেশ করতে চাইছি তা নিশ্চিত করার একটি উপায় কি জিজ্ঞাসাগুলির একটি জুড়ি ব্যবহার না করে ইতিমধ্যে বিদ্যমান নেই (যেমন, একটি জিজ্ঞাসা যাচাই করতে হবে এবং একটি সন্নিবেশ করানোর জন্য ফলাফল সেট হ'ল) খালি)?

একটি করে uniqueএকটি ক্ষেত্র গ্যারান্টি উপর বাধ্যতা insertযদি এটি ইতিমধ্যেই আছে ব্যর্থ হবে?

মনে হয় নিছক একটি সীমাবদ্ধতার সাথে আমি যখন পিএইচপি এর মাধ্যমে সন্নিবেশটি প্রকাশ করি তখন স্ক্রিপ্টটি কুঁকড়ে যায়।



দেখুন stackoverflow.com/questions/44550788/... auto_inc মান জ্বলন্ত না সম্পর্কে আলোচনার জন্য।
রিক জেমস

@RickJames - যে একটি আকর্ষণীয় কুই এসে গেছে .. কিন্তু নিশ্চিত না সরাসরি এই কুই এর সাথে সম্পর্কিত হচ্ছে :)
ওয়ারেন

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

1
ওহ, আমি কখনই পাশের বারটি তাকানোর চিন্তা করি না।
রিক জেমস

উত্তর:


806

ব্যবহার INSERT IGNORE INTO table

দেখতে http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html

এছাড়াও আছে INSERT … ON DUPLICATE KEY UPDATEসিনট্যাক্স, আপনি ব্যাখ্যা জানতে পারেন dev.mysql.com


গুগলের ওয়েবক্যাশ অনুসারে বোগদান.আর্গ. থেকে পোস্ট করুন :

18 ই অক্টোবর 2007

শুরু করার জন্য: সর্বশেষ মাইএসকিউএল হিসাবে শিরোনামে উপস্থাপন করা সিনট্যাক্স সম্ভব নয়। তবে বিদ্যমান কার্যকারিতাটি ব্যবহার করে যা প্রত্যাশা করা হয় তা সম্পাদন করার বেশ কয়েকটি খুব সহজ উপায় রয়েছে।

3 টি সম্ভাব্য সমাধান রয়েছে: INSERT IGNORE, REPLACE, বা INSERT ব্যবহার করে ... কী কী আপডেটের জন্য।

কল্পনা করুন আমাদের একটি টেবিল রয়েছে:

CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar(20) NOT NULL,
`transcript_chrom_start` int(10) unsigned NOT NULL,
`transcript_chrom_end` int(10) unsigned NOT NULL,
PRIMARY KEY (`ensembl_transcript_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

এখন কল্পনা করুন যে এনাম্বেল থেকে ট্রান্সক্রিপ্টগুলি মেটা-ডেটা আমদানি করার একটি স্বয়ংক্রিয় পাইপলাইন রয়েছে এবং বিভিন্ন কারণে এই পাইপলাইনটি কার্যকর করার যে কোনও পদক্ষেপে ভেঙে যেতে পারে। সুতরাং, আমাদের দুটি জিনিস নিশ্চিত করা দরকার:

  1. পাইপলাইনের বারবার মৃত্যুদণ্ড কার্যকর করা আমাদের ডাটাবেসকে ধ্বংস করবে না

  2. 'সদৃশ প্রাথমিক কী'র ত্রুটির কারণে বারবার মৃত্যুদণ্ড কার্যকর হবে না।

পদ্ধতি 1: REPLACE ব্যবহার করে

এটা খুবই সাধারণ:

REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;

রেকর্ডটি বিদ্যমান থাকলে এটি ওভাররাইট করা হবে; এটি এখনও উপস্থিত না থাকলে এটি তৈরি করা হবে। তবে, এই পদ্ধতিটি ব্যবহার করা আমাদের ক্ষেত্রে দক্ষ নয়: আমাদের বিদ্যমান রেকর্ডগুলি ওভাররাইট করার দরকার নেই, কেবল এগুলি এড়িয়ে যাওয়া ঠিক।

পদ্ধতি 2: INSERT IGNORE ব্যবহার করা খুব সহজ:

INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;

এখানে, যদি 'ensembl_transcript_id' ডাটাবেসে ইতিমধ্যে উপস্থিত থাকে, তবে এটি নিঃশব্দে এড়ানো হবে (উপেক্ষা করা হবে)। (আরও সুনির্দিষ্টভাবে বলতে গেলে, এখানে মাইএসকিউএল রেফারেন্স ম্যানুয়ালটির একটি উদ্ধৃতি দেওয়া হয়েছে: "আপনি যদি আইগনোর কীওয়ার্ডটি ব্যবহার করেন তবে INSERT বিবৃতি কার্যকর করার সময় ঘটে যাওয়া ত্রুটিগুলির পরিবর্তে সতর্কতা হিসাবে বিবেচনা করা হবে example উদাহরণস্বরূপ, IGNORE ব্যতীত একটি সারি যা বিদ্যমান ইউনিক্যু সূচকটি নকল করে ates বা সারণীতে প্রাথমিক কী মান একটি সদৃশ-কী ত্রুটির কারণ এবং বিবৃতিটি বাতিল করা হয়েছে orted ")) রেকর্ডটি এখনও উপস্থিত না থাকলে এটি তৈরি করা হবে।

এই দ্বিতীয় পদ্ধতির বেশ কয়েকটি সম্ভাব্য দুর্বলতা রয়েছে, অন্য কোনও সমস্যা দেখা দিলে ক্যোয়ারীর গর্ভপাত না করা সহ (ম্যানুয়ালটি দেখুন)। এর আগে যদি আইগনোর কীওয়ার্ড ছাড়াই পরীক্ষা করা হয় তবে এটি ব্যবহার করা উচিত।

পদ্ধতি 3: INSERT ব্যবহার করা হচ্ছে ... কী কী আপডেটের জন্য ডুপ্লিকেট:

তৃতীয় বিকল্পটি INSERT … ON DUPLICATE KEY UPDATE সিনট্যাক্স ব্যবহার করা , এবং আপডেটের অংশে 0 + 0 গণনা করার মতো কিছু অর্থহীন (খালি) অপারেশন না করে (জিওফ্রে এই অপারেশনটিকে উপেক্ষা করার জন্য মাইএসকিউএল অপ্টিমাইজেশান ইঞ্জিনের জন্য আইডি = আইডি অ্যাসাইনমেন্টটি করার পরামর্শ দেয়)। এই পদ্ধতির সুবিধা হ'ল এটি কেবল সদৃশ কী ইভেন্টগুলি উপেক্ষা করে এবং অন্যান্য ত্রুটিগুলি ত্যাগ করে।

চূড়ান্ত বিজ্ঞপ্তি হিসাবে: এই পোস্টটি Xaprb দ্বারা অনুপ্রাণিত হয়েছিল। আমি নমনীয় এসকিউএল কোয়েরি লিখতে তার অন্যান্য পোস্টের সাথে পরামর্শ করার পরামর্শ দেব।


3
এবং আমি স্ক্রিপ্টটি গতি বাড়ানোর জন্য "বিলম্ব" এর সাথে এটি একত্রিত করতে পারি?
ওয়ারেন

3
হ্যাঁ, বিলম্ব সন্নিবেশ করা আপনার পক্ষে জিনিসগুলির গতি বাড়িয়ে দিতে পারে। এটি ব্যবহার করে দেখুন
নিটল


10
INSERT … ON DUPLICATE KEY UPDATEএটি কোনও auto_incrementকলাম এবং অন্যান্য ডেটা সংরক্ষণ করে সারিটি মোছা না হওয়াই ভাল ।
রিডোল্যান্ট

14
শুধু সবাইকে জানাতে। INSERT … ON DUPLICATE KEY UPDATEপদ্ধতিটি ব্যবহার করা ব্যর্থ সন্নিবেশ সহ যে কোনও AUTO_INCREMENT কলামকে বাড়িয়ে তোলে। সম্ভবত কারণ এটি সত্যই ব্যর্থ হয়নি, তবে আপডেট হবে।
not2qubit

216

সমাধান:

INSERT INTO `table` (`value1`, `value2`) 
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL 
WHERE NOT EXISTS (SELECT * FROM `table` 
      WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1) 

ব্যাখ্যা:

অন্তঃস্থতম ক্যোয়ারী

SELECT * FROM `table` 
      WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1

WHERE NOT EXISTSইতিমধ্যে ডেটা withোকানোর জন্য কোনও সারি উপস্থিত থাকলে শর্তটি সনাক্ত করে used এই ধরণের একটি সারি সন্ধানের পরে, কোয়েরিটি বন্ধ হয়ে যেতে পারে, সুতরাং LIMIT 1(মাইক্রো-অপ্টিমাইজেশন, বাদ দেওয়া যেতে পারে)।

মধ্যবর্তী কোয়েরি

SELECT 'stuff for value1', 'stuff for value2' FROM DUAL

valuesোকানোর জন্য মানগুলি উপস্থাপন করে। DUALএকটি বিশেষ এক সারি বোঝায়, সমস্ত ওরাকল ডাটাবেসে ডিফল্টরূপে একটি কলামের টেবিল উপস্থিত রয়েছে ( https://en.wikedia.org/wiki/DUAL_table দেখুন )। একটি মাইএসকিউএল-সার্ভার সংস্করণে 7.7.২6 বাদ দিলে আমি একটি বৈধ প্রশ্ন পেয়েছি FROM DUALতবে পুরানো সংস্করণগুলিতে (৫.৫.60০ এর মতো) FROMতথ্যের প্রয়োজন বলে মনে হচ্ছে । WHERE NOT EXISTSঅন্তর্বর্তী ক্যোয়ারী ব্যবহার করে একটি খালি ফলাফল সেট ফেরত দেয় যদি অন্তর্নিহিত কোয়েরিতে মিলিত ডেটা পাওয়া যায়।

বাইরের কোয়েরি

INSERT INTO `table` (`value1`, `value2`) 

মধ্যবর্তী ক্যোয়ারী দ্বারা যদি কোনও ফেরত দেওয়া হয় তবে ডেটা সন্নিবেশ করান।


4
আপনি কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে আরও কিছু তথ্য দিতে পারেন?
অ্যালেক্স ভি

36
এই বৈকল্পিকটি উপযুক্ত যদি টেবিলে কোনও অনন্য কী উপস্থিত না থাকে ( INSERT IGNOREএবং INSERT ON DUPLICATE KEYঅনন্য কী বাধাগুলির প্রয়োজন হয়)
রাবুদে

2
যদি আপনি "টেবিল থেকে" পরিবর্তে লাইন 2 তে "দ্বৈত থেকে" ব্যবহার করেন, তবে আপনার "সীমা 1" ধারাটির প্রয়োজন হবে না।
ধনী

6
যদি stuff for value1এবং stuff for value2অভিন্ন হয়? এটি ছুড়ে ফেলবেDuplicate column name
রবিন

1
আমি সাবকিউয়ের SELECT 1পরিবর্তে অনেক পছন্দ করি SELECT *। আরও অনেক বেশি সম্ভবত এটি কোনও সূচক দ্বারা সন্তুষ্ট হতে পারে।
আর্থ

58

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


Mysql.com এর উপর ভিত্তি করে ডুপ্লিকেট কী আপডেট আপডেটের উদাহরণ

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

UPDATE table SET c=c+1 WHERE a=1;

Mysql.com- এর ভিত্তিতে সন্নিবেশ করানোর উদাহরণ

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

বা:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

বা:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

24

কোনও সাধারণ বাধা কাজটি করা উচিত, যদি কোনও ব্যতিক্রম গ্রহণযোগ্য হয়। উদাহরণ:

  • সার্গেট না হলে প্রাথমিক কী
  • একটি কলামে অনন্য বাধা
  • বহু কলাম অনন্য সীমাবদ্ধতা

দুঃখিত যে এটি ছদ্মবেশী সহজ বলে মনে হচ্ছে। আমি জানি আপনি আমাদের সাথে যে লিঙ্কটি ভাগ করেছেন তাতে এটির মুখোমুখি খারাপ লাগছে। ;-(

তবে আমি নিরলস এই উত্তরটি দিচ্ছি না কারণ এটি আপনার প্রয়োজনীয়তা পূরণ করে। (যদি তা না হয় তবে এটি আপনার প্রয়োজনীয়তাগুলি আপডেট করার জন্য ট্রিগার করতে পারে, এটি "একটি ভাল জিনিস" (টিএম )ও হবে)।

সম্পাদিত : যদি একটি সন্নিবেশ ডাটাবেস অনন্য সীমাবদ্ধতা ভঙ্গ করে, একটি ব্যতিক্রম ডাটাবেস স্তরে নিক্ষেপ করা হয়, ড্রাইভার দ্বারা রিলে করা হয়। এটি অবশ্যই আপনার স্ক্রিপ্টটি বন্ধ করবে, ব্যর্থতার সাথে। পিএইচপি-তে অবশ্যই এই কেসটিকে সম্বোধন করা সম্ভব ...


1
আমি প্রশ্নের একটি স্পষ্টতা যোগ করেছি - আপনার উত্তর এখনও প্রযোজ্য?
ওয়ারেন 9

2
আমি বিশ্বাস করি। একটি অনন্য বাধা ভুল সন্নিবেশগুলির ব্যর্থতার কারণ ঘটবে। দ্রষ্টব্য: আপনার কোডে এই ব্যর্থতা মোকাবেলা করতে হবে, তবে এটি বেশ প্রমিত।
কেএমই

1
আপাতত আমি যে সমাধানটি গ্রহণ করেছি তার সাথে তাল মিলিয়ে যাচ্ছি - তবে অ্যাপটি বাড়ার সাথে সাথে INSERT ব্যর্থতা ইত্যাদি পরিচালনা করার বিষয়ে আরও তাকাব
ওয়ারেন্ট

3
INSERT IGNOREমূলত সমস্ত ত্রুটি সতর্কতাগুলিতে পরিবর্তন করে যাতে আপনার স্ক্রিপ্ট বাধা না দেয়। এরপরে আপনি কমান্ডটি সহ যে কোনও সতর্কতা দেখতে পাবেন SHOW WARNINGS। এবং অন্য গুরুত্বপূর্ণ নোট : অনন্য সীমাবদ্ধতাগুলি NULL মানগুলির সাথে কাজ করে না, যেমন। সারি 1 (1, NULL) এবং সারি 2 (1, NULL) উভয়ই সন্নিবেশ করানো হবে (অন্য কোনও বাধা যেমন একটি প্রাথমিক কী ভাঙ্গা না দেওয়া)। দু: খজনক।
সাইমন পূর্ব

18

এখানে একটি পিএইচপি ফাংশন রয়েছে যা কেবলমাত্র সমস্ত নির্দিষ্ট কলামের মান সারণীতে উপস্থিত না থাকলে কেবল একটি সারি সন্নিবেশ করবে।

  • কলামগুলির মধ্যে একটি পৃথক হলে সারি যুক্ত করা হবে।

  • টেবিলটি খালি থাকলে সারি যুক্ত করা হবে।

  • সমস্ত সুনির্দিষ্ট কলামগুলিতে নির্দিষ্ট মান রয়েছে সেখানে সারি উপস্থিত থাকলে, সারিটি যুক্ত করা হবে না।

    function insert_unique($table, $vars)
    {
      if (count($vars)) {
        $table = mysql_real_escape_string($table);
        $vars = array_map('mysql_real_escape_string', $vars);
    
        $req = "INSERT INTO `$table` (`". join('`, `', array_keys($vars)) ."`) ";
        $req .= "SELECT '". join("', '", $vars) ."' FROM DUAL ";
        $req .= "WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE ";
    
        foreach ($vars AS $col => $val)
          $req .= "`$col`='$val' AND ";
    
        $req = substr($req, 0, -5) . ") LIMIT 1";
    
        $res = mysql_query($req) OR die();
        return mysql_insert_id();
      }
    
      return False;
    }

ব্যবহারের উদাহরণ:

<?php
insert_unique('mytable', array(
  'mycolumn1' => 'myvalue1',
  'mycolumn2' => 'myvalue2',
  'mycolumn3' => 'myvalue3'
  )
);
?>

5
আপনার কাছে বিশাল পরিমাণ সন্নিবেশ থাকলে খুব ব্যয়বহুল।
অ্যাড আদুলাДь

সত্য, তবে কার্যকর যদি আপনার নির্দিষ্ট চেকআপগুলি যুক্ত করতে হয়
চার্লস ফরেস্ট

1
সতর্কতা: mysql_* এক্সটেনশন পিএইচপি 5.5.0 হিসাবে অবচিত করা হয়েছে এবং পিএইচপি 7.0.0 হিসাবে সরানো হয়েছে। পরিবর্তে, হয় mysqli বা PDO_MySQL এক্সটেনশন ব্যবহার করা উচিত। আরও দেখুন মাইএসকিউএল এপিআই সংক্ষিপ্ত বিবরণ আরও সাহায্যের জন্য যখন একটি মাইএসকিউএল এপিআই নির্বাচন।
ধর্মান 20:00

17
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;

রেকর্ডটি বিদ্যমান থাকলে এটি ওভাররাইট করা হবে; এটি এখনও উপস্থিত না থাকলে এটি তৈরি করা হবে।


10
REPLACEসারিটি মুছে ফেলতে পারে এবং তারপরে আপডেটের পরিবর্তে সন্নিবেশ করতে পারে। পার্শ্ব প্রতিক্রিয়া হ'ল সীমাবদ্ধতাগুলি অন্যান্য অবজেক্টগুলি মুছে ফেলতে পারে এবং মুছে ফেলা ট্রিগারগুলি নষ্ট হয়ে যায়।
xmedeko

1
মাইএসকিউএল ম্যানুয়াল থেকে: "কোনও টেবিলের কাছে প্রাথমিক কী বা ইউনিক ইনডেক্স থাকে কেবল তখনই পরিবর্তনটি বোধগম্য হয় Otherwise
বার্নিনলিও

16

নিম্নলিখিত চেষ্টা করুন:

IF (SELECT COUNT(*) FROM beta WHERE name = 'John' > 0)
  UPDATE alfa SET c1=(SELECT id FROM beta WHERE name = 'John')
ELSE
BEGIN
  INSERT INTO beta (name) VALUES ('John')
  INSERT INTO alfa (c1) VALUES (LAST_INSERT_ID())
END

5
এই উত্তরগুলি স্ট্যাকওভারফ্লোতে স্বল্প-মূল্যবান কারণ তারা ওপি এবং হাজার হাজার ভবিষ্যত গবেষককে শিক্ষিত করতে খুব কম কাজ করে। সমাধানটি কীভাবে কাজ করে এবং কেন এটি একটি ভাল ধারণা তা অন্তর্ভুক্ত করার জন্য দয়া করে এই উত্তরটি সম্পাদনা করুন।
মিকম্যাকুসা

1
ম্যাচের ক্ষেত্রগুলি কীগুলি না হওয়ার ক্ষেত্রে নিখুঁত সমাধান ..!
লিও

6

বেশ কয়েকটি উত্তর রয়েছে যেগুলি কীভাবে সমাধান করতে হয় তা যদি আপনার কোনও UNIQUEসূচক থাকে যা আপনি এর সাথে ON DUPLICATE KEYবা এর সাথে চেক করতে পারেন INSERT IGNORE। এটি সর্বদা ক্ষেত্রে হয় না এবং UNIQUEদৈর্ঘ্যের সীমাবদ্ধতা (1000 বাইট) আপনি এটি পরিবর্তন করতে পারবেন না। উদাহরণস্বরূপ, আমাকে ওয়ার্ডপ্রেসে মেটাডেটা নিয়ে কাজ করতে হয়েছিল ( wp_postmeta)।

শেষ পর্যন্ত আমি দুটি প্রশ্নের সাথে এটি সমাধান করেছি:

UPDATE wp_postmeta SET meta_value = ? WHERE meta_key = ? AND post_id = ?;
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) SELECT DISTINCT ?, ?, ? FROM wp_postmeta WHERE NOT EXISTS(SELECT * FROM wp_postmeta WHERE meta_key = ? AND post_id = ?);

প্রশ্ন 1 হ'ল একটি নিয়মিত UPDATEক্যোয়ারী, যখন প্রশ্নে থাকা ডেটাসেটটি নেই তখন কোনও প্রভাব নেই। ক্যোয়ারি 2 হ'ল একটি INSERTযা নির্ভর করে NOT EXISTSযেমন, INSERTযখন ডেটাসেটের অস্তিত্ব থাকে না তখনই তা কার্যকর করা হয়।


2

কিছু বিষয় লক্ষণীয় যে INSERT IGNORE এখনও বিবৃতিটি সাফল্য ছিল কিনা ঠিক সাধারণ INSERT এর মতো নয় তা প্রাথমিক কী বাড়িয়ে দেবে।

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

দেখুন innodb_autoinc_lock_mode = 0(সার্ভার সেটিং, এবং একটি সামান্য পারফরম্যান্স হিট সঙ্গে আসে), বা আপনার ক্যোয়ারী ব্যর্থ হবে না তা নিশ্চিত করতে প্রথমে একটি নির্বাচন নির্বাচন করুন (এটি একটি পারফরম্যান্স হিট এবং অতিরিক্ত কোড সহও আসে)।


কেন "আপনার প্রাথমিক কীগুলির ফাঁক" - এমনকি সম্ভাব্য - "একজন প্রোগ্রামারকে মানসিকভাবে অস্থির করতে" কেন? প্রাথমিক কীগুলিতে সমস্ত সময় গ্যাপগুলি দেখা যায় - প্রতিবার আপনি কোনও রেকর্ড মুছুন, উদাহরণস্বরূপ।
ওয়ারেন

একটি দিয়ে শুরু SELECTপরাজয় শুধু হস্তান্তর বন্ধ একটি বড় ব্যাচ পুরো উদ্দেশ্য INSERTs এবং সদৃশ সম্পর্কে চিন্তা করতে অনুপস্থিত না।
ওয়ারেন

2

জ্ঞাত প্রাথমিক কী ব্যতীত আপডেট বা সন্নিবেশ করান

আপনার যদি ইতিমধ্যে একটি অনন্য বা প্রাথমিক কী থাকে তবে অন্য উত্তরগুলির সাথে হয় INSERT INTO ... ON DUPLICATE KEY UPDATE ...বা REPLACE INTO ...ঠিকঠাক কাজ করা উচিত (নোটগুলি উপস্থিত থাকলে মুছে ফেলা এবং তারপরে সন্নিবেশ করানো উচিত - সুতরাং বিদ্যমান মানগুলি আংশিকভাবে আপডেট করে না)।

তবে আপনার যদি মানগুলি থাকে some_column_idএবং some_typeএর সমন্বয়টি অনন্য হিসাবে পরিচিত। এবং আপনি some_valueউপস্থিত থাকলে আপডেট করতে চান বা উপস্থিত না থাকলে inোকাতে চান। এবং আপনি এটি কেবল একটি ক্যোয়ারিতে করতে চান (কোনও লেনদেন ব্যবহার এড়াতে)। এটি একটি সমাধান হতে পারে:

INSERT INTO my_table (id, some_column_id, some_type, some_value)
SELECT t.id, t.some_column_id, t.some_type, t.some_value
FROM (
    SELECT id, some_column_id, some_type, some_value
    FROM my_table
    WHERE some_column_id = ? AND some_type = ?
    UNION ALL
    SELECT s.id, s.some_column_id, s.some_type, s.some_value
    FROM (SELECT NULL AS id, ? AS some_column_id, ? AS some_type, ? AS some_value) AS s
) AS t
LIMIT 1
ON DUPLICATE KEY UPDATE
some_value = ?

মূলত, ক্যোয়ারীটি এভাবে চালিত করে (যত কম দেখায় তত জটিল):

  • WHEREক্লজ ম্যাচের মাধ্যমে একটি বিদ্যমান সারি নির্বাচন করুন ।
  • সম্ভাব্য নতুন সারি (টেবিল s) সহ ইউনিয়ন , যেখানে কলামের মানগুলি স্পষ্টভাবে দেওয়া হয়েছে (s.id হল NULL, সুতরাং এটি একটি নতুন অটো-ইনক্রিমেন্ট সনাক্তকারী তৈরি করবে)।
  • একটি বিদ্যমান সারি পাওয়া যায়, তাহলে টেবিল থেকে সম্ভাব্য নতুন সারি sবাতিল করা হয় (টেবিলের উপর সীমা 1 কারণে t), এবং এটা সবসময় একটি আরম্ভ হবে ON DUPLICATE KEYযা হবে কলাম।UPDATEsome_value
  • যদি একটি বিদ্যমান সারি পাওয়া যায় না, তখন সম্ভাব্য নতুন সারি ঢোকানো হয় (সারণী দেওয়া s)।

দ্রষ্টব্য: আপেক্ষিক ডাটাবেসের প্রতিটি টেবিলের কমপক্ষে একটি প্রাথমিক অটো-ইনক্রিমেন্ট idকলাম থাকা উচিত। আপনার যদি এটি না থাকে তবে এটিকে যুক্ত করুন, এমনকি আপনার প্রথম দর্শনে এটির প্রয়োজন নেই। এটি অবশ্যই এই "কৌশল" এর জন্য প্রয়োজন।


অন্যান্য বেশ কয়েকটি উত্তরদাতা একটি INSERT INTO ... SELECT FROMফর্ম্যাট লাভ করেছেন। তুমিও কেন?
ওয়ারেন

2
@ ওওয়ারেন হয় আপনি আমার উত্তরটি পড়েননি, আপনি তা বুঝতে পারেন না, বা আমি এটি সঠিকভাবে ব্যাখ্যা করিনি। যাইহোক, আমি নিম্নলিখিত জোর দেওয়া যাক: এটি কেবল একটি নিয়মিত INSERT INTO... SELECT FROM...সমাধান নয়। দয়া করে আমাকে একটি উত্তরের লিঙ্কটি উল্লেখ করুন যা একই, আপনি যদি এটির সন্ধান করতে পারেন তবে আমি এই উত্তরটি মুছে ফেলব, নইলে আপনি আমার উত্তরটিকে আপলোড করবেন (ডিল?)। আপনি যে উত্তরটি লিঙ্ক করতে চলেছেন তা কেবল 1 টি ক্যোয়ারী (আপডেট + সন্নিবেশের জন্য), কোনও লেনদেন ব্যবহার করে না তা যাচাই করতে ভুলবেন না এবং স্বতন্ত্র হিসাবে পরিচিত কলামগুলির এমন কোনও সংমিশ্রণ লক্ষ্যবস্তু করতে সক্ষম (তাই কলামগুলি পৃথকভাবে পৃথক নয়) অনন্য হতে হবে)।
ইয়েতি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.