ওরাকল এসকিউএল: অন্য টেবিলের ডেটা সহ একটি টেবিল আপডেট করুন


251

1 নং টেবিল:

id    name    desc
-----------------------
1     a       abc
2     b       def
3     c       adf

টেবিল ২:

id    name    desc
-----------------------
1     x       123
2     y       345

ওরাকল SQL এর যে, কিভাবে আমি একটি চালানো SQL আপডেট কোয়েরি যে টেবিল 2 এর সঙ্গে সারণি 1 আপডেট করতে পারেন nameএবং descএকই ব্যবহার id? সুতরাং আমি শেষ ফলাফল হবে

1 নং টেবিল:

id    name    desc
-----------------------
1     x       123
2     y       345
3     c       adf

প্রশ্ন অন্য একের ডেটা সহ এক টেবিল আপডেট থেকে নেওয়া হয় , তবে বিশেষত ওরাকল এসকিউএল জন্য।



আপনাকে আপনার অন্য প্রশ্নে ফিরে যেতে হবে, সেই উত্তরটি অ-স্বীকার করতে হবে এবং বিশেষত উল্লেখ করতে হবে যে আপনার ওরাকল পিএলএসকিউএল সিনট্যাক্সের প্রয়োজন।
পি.কম্পবেল

3
@ পি ক্যাম্পবেল, এটি আমার প্রশ্ন নয় ...
মুহাদ

1
আচ্ছা বুঝলাম. সুতরাং আপনি প্রশ্নবঙ্গটি অনুলিপি-পেস্ট করেছেন, তবে ওরাকল বিটটি অন্তর্ভুক্ত করতে সংশোধিত করেছেন।
পি.কম্পবেল

2
হ্যাঁ। এবং এটি সম্ভবত সেরা উদাহরণ নয় কারণ "ডেস্ক" একটি সংরক্ষিত শব্দ, তবে ওহ ভাল।
মুহিত

উত্তর:


512

একে একে সম্পর্কিত সম্পর্কিত আপডেট বলা হয়

UPDATE table1 t1
   SET (name, desc) = (SELECT t2.name, t2.desc
                         FROM table2 t2
                        WHERE t1.id = t2.id)
 WHERE EXISTS (
    SELECT 1
      FROM table2 t2
     WHERE t1.id = t2.id )

কী-সংরক্ষিত দৃশ্যে যোগদানের ফলাফলগুলি ধরে নেওয়া, আপনি এটিও করতে পারেন

UPDATE (SELECT t1.id, 
               t1.name name1,
               t1.desc desc1,
               t2.name name2,
               t2.desc desc2
          FROM table1 t1,
               table2 t2
         WHERE t1.id = t2.id)
   SET name1 = name2,
       desc1 = desc2

8
আপনার প্রথম কোডের উদাহরণে: সঠিক ফলাফলের জন্য কি বাইরের WHERE-ধারা প্রয়োজন? অথবা আপনি কেবল এটির অনুসন্ধানের জন্যই ব্যবহার করছেন?
ম্যাথিয়াস Bader

41
@ টোটোরো - প্রথম উদাহরণে, কোনও মিল নেই সারণী যদি WHERE EXISTSনা t1থাকে তবে আপনাকে কোনও সারি আপডেট করতে বাধা দেয় t2। এটি ছাড়াই, প্রতিটি সারি t1আপডেট করা হবে এবং এর NULLসাথে কোনও মিলের সারি না থাকলে মানগুলি সেট করা হবে t2। এটি সাধারণত আপনি যা করতে চান তা তাই হয় না WHERE EXISTSযা সাধারণত প্রয়োজন হয়।
জাস্টিন গুহ

3
এটি যুক্ত করা দরকার যে SELECT ... FROM t2 অবশ্যই একটি অনন্য সারিতে ফলস্বরূপ। এর অর্থ হ'ল আপনাকে এমন সমস্ত ক্ষেত্র বাছাই করতে হবে যা একটি অনন্য কী যুক্ত করে - একটি অনন্য-অনন্য প্রাথমিক কী যথেষ্ট নয়। স্বতন্ত্রতা ছাড়াই, আপনি @ পলকারারের লুপের মতো কিছুতে হ্রাস পেয়েছেন - এবং যদি কোনও অনন্য সম্পর্ক নেই তবে প্রতিটি উত্স সারির জন্য একাধিক লক্ষ্য সারি আপডেট করা যেতে পারে।
অ্যান্ড্রু লিচ

2
Updatable জন্য কী সংরক্ষিত প্রয়োজন উপর ব্যাখ্যা যোগদান করে: asktom.oracle.com/pls/asktom/...
Vadzim

1
@ রচিতশর্মা - এর অর্থ হ'ল আপনার সাবকোয়ারি (এর ক্যোয়ারী table2) এক বা একাধিক table1মানের জন্য একাধিক সারি ফিরছে এবং ওরাকল জানে না আপনি কোনটি ব্যবহার করতে চান। সাধারণত, এর অর্থ হল যে আপনাকে সাবকোয়ারিটি পরিমার্জন করতে হবে যাতে এটি একটি পৃথক সারিতে ফিরে আসে।
জাস্টিন গুহ

132

এটা চেষ্টা কর:

MERGE INTO table1 t1
USING
(
-- For more complicated queries you can use WITH clause here
SELECT * FROM table2
)t2
ON(t1.id = t2.id)
WHEN MATCHED THEN UPDATE SET
t1.name = t2.name,
t1.desc = t2.desc;

4
খুব দ্রুত প্রকৃতপক্ষে, 1159477 সারি 15,5 সেগুলিতে একীভূত হয়েছে
jefissu

3
আমি আশা করি 2015 এর পরে এই প্রশ্নটি প্রত্যেকে দেখে এই উত্তরটি লক্ষ্য করুন। নোট এই কাজ করে যদি table1এবং table2একই টেবিল হয়, শুধু যত্ন নিতে ONএবং -part WHEREজন্য -clause SELECTএর -statement table2!
sjngm

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

মোহন মত কাজ !! ধন্যবাদ!
ডেভিডওয়িলিয়ানেক্স

নির্বাচন করুন আইডি, ফিল্ড 1, টেবিল 2 থেকে ফিল্ড 1 যেখানে আইডি নাল নয়
জোসেফ

17

চেষ্টা

UPDATE Table1 T1 SET
T1.name = (SELECT T2.name FROM Table2 T2 WHERE T2.id = T1.id),
T1.desc = (SELECT T2.desc FROM Table2 T2 WHERE T2.id = T1.id)
WHERE T1.id IN (SELECT T2.id FROM Table2 T2 WHERE T2.id = T1.id);

4
এর নেতিবাচক দিকটি হ'ল SELECT স্টেটমেন্টটি 3 বার পুনরাবৃত্তি করা হয়। জটিল উদাহরণগুলিতে যা একটি চুক্তি-ব্রেকার হতে পারে।
ডেভিড বালেক

9
Update table set column = (select...)

সেটটি কেবলমাত্র 1 টির জন্য প্রত্যাশা রাখেনি - এসকিউএল ত্রুটি: ORA-01427: একক-সারি সাবকিউরি একাধিক সারির চেয়ে বেশি দেয়।

সমাধান এখানে:

BEGIN
For i in (select id, name, desc from table1) 
LOOP
Update table2 set name = i.name, desc = i.desc where id = i.id;
END LOOP;
END;

আপনি এটি ঠিক কীভাবে এসকিউএল ডেভেলপার ওয়ার্কশিটে চালান। তারা বলছেন যে এটি ধীর গতিতে তবে এটিই একমাত্র সমাধান যা এই ক্ষেত্রে আমার পক্ষে কাজ করেছিল।


কেউ দয়া করে ব্যাখ্যা করতে পারেন কেন এটি খ্যাতির উপর -2 প্রাপ্য? হাঃ হাঃ হাঃ.
পাউ কার

13
আমি রেট ডাউন করিনি, তবে এটি কোনও ভাল সমাধান নয়। প্রথমত: যদি সাবজেক্টটি একাধিক মান প্রত্যাবর্তন করে, তবে লুপের জন্য টেবিল 2 এ নামটি কয়েকটি / সমস্ত রেকর্ডের জন্য পরিষ্কার করা হবে (পরিষ্কার নয়)। দ্বিতীয়ত: ধারা দ্বারা কোনও অর্ডার নেই সুতরাং এটি একটি অনাকাঙ্ক্ষিত পদ্ধতিতে ঘটবে (অর্থাত্ আনর্ডার্ডযুক্ত ডেটা জয়ের শেষ মান)। তৃতীয়ত: এটি অনেক ধীর হবে। লুপের ফলাফলটির উদ্দেশ্য ছিল তা ধরে নিলে, মূল সাবলেটটি প্রতিটি রেকর্ডের জন্য কেবল 1 টি মান ফেরত দেওয়ার জন্য কিছু নিয়ন্ত্রিত উপায়ে আবারও লেখা যেতে পারে ... সহজতর স্বীকৃত উপায় হ'ল (নির্বাচন করুন মিনিট (নাম) ...)
অল্টারনেটার

এটি আমার প্রয়োজন ঠিক ছিল। ধন্যবাদ (+1)
রবার্ট হায়াত

3
আপনি যদি আপনার সাবকিউয়েরিতে একাধিক মান পেয়ে থাকেন তবে আপনি এই ক্যোয়ারীটি পুনর্বিবেচনা করতে পারেন এবং ডিআইএনএসআইএনটি বা এমআইএন, ম্যাক্স সহ গ্রুপ ব্যবহার করতে পারেন। শুধু একটি ধারণা।
ফ্রান্সিস

দীর্ঘ গল্প সংক্ষিপ্ত: আপনি যদি এটিকে এড়াতে পারেন তবে কখনও কখনও কোনও টি-এসকিউএল বিবৃতিতে কোনও ধরণের লুপ ব্যবহার করবেন না। ব্যক্তিগতভাবে, যদি এটি 0.001% এর সময় না হয় যেখানে অন্য কোনও সমাধান নেই, আমি এমনকি টি-এসকিউএল-তে এটি একটি উপলব্ধ ফাংশন হওয়া উচিত বলেও মনে করি না। টি-এসকিউএল সেট-বেসড করার জন্য ডিজাইন করা হয়েছে, সুতরাং এটি সামগ্রিকভাবে ডেটার সম্পূর্ণ সেটগুলিতে কাজ করে; এটি লাইন বাই লাইনে ডেটাতে কাজ করার জন্য ব্যবহার করা উচিত নয়।
রায় কে।

8

এখানে 'ইন' ধারাটির সাথে আরও উত্তম উত্তর বলে মনে হচ্ছে যা যোগদানের জন্য একাধিক কীগুলির জন্য অনুমতি দেয় :

update fp_active set STATE='E', 
   LAST_DATE_MAJ = sysdate where (client,code) in (select (client,code) from fp_detail
  where valid = 1) ...

গরুর মাংসের কলামগুলি এমন যে কলামগুলিতে আপনি যেটি বন্ধনীতে কী হিসাবে ব্যবহার করতে চান সেখানে রয়েছে যেখানে 'ইন' এর আগে এবং বন্ধনীগুলিতে একই কলামের নামের সাথে নির্বাচনী বিবৃতি রয়েছে। যেখানে ( কলাম 1, কলাম 2 ) ( নির্বাচন করুন ( কলাম 1, কলাম 2 ) টেবিল থেকে যেখানে "আমি চাই সেট" );


লিঙ্কটির মেয়াদ শেষ হয়ে গেছে। ( 404)
ডাম্বো

-3

যদি আপনার টেবিল টি 1 এবং এটির ব্যাকআপ টি 2 এর অনেকগুলি কলাম রয়েছে, এটি করার জন্য এখানে একটি কমপ্যাক্ট উপায়।

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

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

কৌশলটি হ'ল আপনি যখন ডুপ্লিকেট কলামের নাম যুক্ত টেবিলগুলির একটি জোড়া থেকে * নির্বাচন করবেন, তখন ২ য় নামটির নাম _1 হবে। সুতরাং আমি এখানে যা এলাম তা এখানে:

  update (
    select * from t1 join t2 on t2.id = t1.id
    where id in (
      select id from (
        select id, col1, col2, ... from t2
        minus select id, col1, col2, ... from t1
      )
    )
  ) set col1=col1_1, col2=col2_1, ...

এটি ওরাকল 11 জি-তে আমার পক্ষে কাজ করে না। আপনি কি এই পদ্ধতির কাজের উদাহরণ তৈরি করতে পারেন?
জন হেলার

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