ওরাকলে অভ্যন্তরীণ যোগ দিয়ে স্টেটমেন্ট আপডেট করুন


297

আমার একটি ক্যোয়ারী রয়েছে যা মাইএসকিউএল-এ ঠিকঠাক কাজ করে তবে আমি যখন ওরেकल এ চালাই তখন আমি নিম্নলিখিত ত্রুটিটি পাই:

এসকিউএল ত্রুটি: ORA-00933: এসকিউএল কমান্ড সঠিকভাবে 00933 শেষ হয়নি
not 00000 - "এসকিউএল কমান্ড সঠিকভাবে শেষ হয়নি"

প্রশ্নটি হ'ল:

UPDATE table1
INNER JOIN table2 ON table1.value = table2.DESC
SET table1.value = table2.CODE
WHERE table1.UPDATETYPE='blah';

আমার উত্তরটি পরীক্ষা করার জন্য যখন আমি ওরাকলে টেবিল 2 সেটআপ করার চেষ্টা করেছি তখন আমি দেখতে পেলাম যে ওরাকল DESC কে কলামের নাম হিসাবে প্রত্যাখ্যান করেছে।
জেনেক বোগুকি

দুঃখিত আমি মূল কলামটির নামটি সংক্ষেপে সংক্ষেপে
ডিবিকে প্রকাশ করেছি

উত্তর:


411

এই সিনট্যাক্সটি ওরাকলে বৈধ নয়। তুমি এটি করতে পারো:

UPDATE table1 SET table1.value = (SELECT table2.CODE
                                  FROM table2 
                                  WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
            FROM table2 
            WHERE table1.value = table2.DESC);

অথবা আপনি পারে এই কাজ করতে সক্ষম হতে হবে:

UPDATE 
(SELECT table1.value as OLD, table2.CODE as NEW
 FROM table1
 INNER JOIN table2
 ON table1.value = table2.DESC
 WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW

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


5
আমি দ্বিতীয় উদাহরণটি করেছিলাম তবে নির্বাচনের কলামের নামগুলির সাথে উপকরণগুলি যুক্ত করতে হয়েছিল এবং তারপরে সেটে তাদের নামগুলি দিয়ে রেফারেন্স করতে হয়েছিল তবে এটি কার্যকর হয়েছে, ধন্যবাদ
গুস্তাভো রুবিও

41
দ্বিতীয় উদাহরণটিতে আপনাকে আপডেটটি সম্পাদন করার আগে আপনাকে এসকিউএল পরীক্ষা করার অনুমতি দেওয়ার সুবিধা রয়েছে।
ড্যানিয়েল রেইস

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

5
দ্বিতীয়টি আমার জন্য কাজ করেছে :)। ওরাকল হ'ল একটি শক্তিশালী তবে অদ্ভুত প্রাণী: /
এলোরাডো

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

202

এটা ব্যবহার কর:

MERGE
INTO    table1 trg
USING   (
        SELECT  t1.rowid AS rid, t2.code
        FROM    table1 t1
        JOIN    table2 t2
        ON      table1.value = table2.DESC
        WHERE   table1.UPDATETYPE='blah'
        ) src
ON      (trg.rowid = src.rid)
WHEN MATCHED THEN UPDATE
    SET trg.value = code;

2
নিখুঁতভাবে কাজ করে তবে ওরাকল আমাকে আরও কিছু বলার দরকার merge into table 1 tপড়েছিল।
মাইকেল-হে

1
পার্টিতে দেরীতে, তবে এটি এখনও একটি ভাল থ্রেড। আমার জানা দরকার, তবে ... ... আমি কিছু মিস করেছি? মাস্টার টেবিল, "টেবিল 1"। ব্যবহারের ক্ষেত্রে, টেবিল 1 টি 1 হিসাবে প্রেরণ করা হয়েছে। টেবিল 2, টি 2 হিসাবে উপস্থাপিত, তবে অনে, উল্লেখগুলি ...? বাহ্যিক টেবিল 1 - টি 1 নয় - এটি কি বাইরের টেবিলের কোনও রেফারেন্স বা কোনও ধরণের? টেবিল ২? টি 2 নয়? Je suis বিভ্রান্ত। আরও ভাল উপাধির ফ্যান ...
মার্ক

এখানে মাত্র একটি বিন্দুতে, যদি আপনার কী (ট্রিগ্রেইউইড বা এসসিআর.আর.আরডি) একটি নকল আইটেম থাকে তবে এই ধারাটিতে
হেনরিক

@ মার্ক ইন ON, trgমাস্টার টেবিলের জন্য উপনাম, table1(আপনার যুক্তি দ্বারা "বাহ্যিক" টেবিল), এবং গোষ্ঠীটি srcউল্লেখ করেছে USING(আপনার যুক্তির দ্বারা "অভ্যন্তরীণ সারণী")। তবে হ্যাঁ, সম্ভবত আরও ভাল রেফারেন্স করা যেতে পারে, কিন্তু আমি এটি অনুসরণ করতে সক্ষম ছিল।
vapcguy

1
@ সুপার্নোভা: টনির উত্তর একটি ইনলাইন ভিউ আপডেট করছে। এটি কিছু ক্ষেত্রে কাজ করতে পারে তবে ভিউটি "কী-সংরক্ষিত" থাকতে হবে (প্রতিটি যোগদানের টেবিলটি তার প্রাথমিক কী বা অন্যথায় অনন্য ফিল্ডসেটে সমতা-যুক্ত হতে হবে)। এটি নিশ্চিত করে যে লক্ষ্য সারণীর প্রতিটি রেকর্ড ফলাফল সারিটি সজ্জায় সর্বাধিক এক রেকর্ডে অবদান রাখে এবং তাই লক্ষ্য টেবিলের প্রতিটি রেকর্ড একবারে আপডেট হয়।
কাসনসুই

25

MERGEসঙ্গে WHEREদফা:

MERGE into table1
USING table2
ON (table1.id = table2.id)
WHEN MATCHED THEN UPDATE SET table1.startdate = table2.start_date
WHERE table1.startdate > table2.start_date;

আপনার WHEREক্লজ দরকার কারণ ধারাটিতে রেফারেন্সযুক্ত কলামগুলি ONআপডেট করা যায় না।


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


11

উপরের কিছু উত্তর ব্যবহার করবেন না।

কেউ কেউ নেস্টেড SELECT ব্যবহারের পরামর্শ দেয়, এটি করবেন না, এটি উদ্বেগজনকভাবে ধীরে ধীরে। আপডেট করার জন্য যদি আপনার কাছে প্রচুর রেকর্ড থাকে তবে যোগদান ব্যবহার করুন, তাই এরকম কিছু:

update (select bonus 
        from employee_bonus b 
        inner join employees e on b.employee_id = e.employee_id 
        where e.bonus_eligible = 'N') t
set t.bonus = 0;

আরও তথ্যের জন্য এই লিঙ্কটি দেখুন। http://geekswithblogs.net/WillSmith/archive/2008/06/18/oracle-update-with-join-again.aspx

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


7

এখানে যেমন নির্দেশিত হয়েছে , টনি অ্যান্ড্রুজের প্রস্তাবিত প্রথম সমাধানের সাধারণ বাক্য গঠনটি হ'ল:

update some_table s
set   (s.col1, s.col2) = (select x.col1, x.col2
                          from   other_table x
                          where  x.key_value = s.key_value
                         )
where exists             (select 1
                          from   other_table x
                          where  x.key_value = s.key_value
                         )

আমি মনে করি এটি আকর্ষণীয় বিশেষত যদি আপনি একাধিক ক্ষেত্র আপডেট করতে চান।


এটি আমার পক্ষে কাজ করে না। এটি পুরো টেবিল আপডেট করে।
নাটাসিয়া টাভারেস

3

এই নিম্নলিখিত সিনট্যাক্সটি আমার পক্ষে কাজ করে।

UPDATE
(SELECT A.utl_id,
    b.utl1_id
    FROM trb_pi_joint A
    JOIN trb_tpr B
    ON A.tp_id=B.tp_id Where A.pij_type=2 and a.utl_id is null
)
SET utl_id=utl1_id;

@ জিমগারিসন দয়া করে এই উত্তরটি পুনরায় সম্পাদনা করুন যাতে আমি আমার ডাউনটোটটি সরিয়ে ফেলতে পারি .... আমি এই বাক্য গঠনটি ব্যবহার করার চেষ্টা করছিলাম এবং এটি আমার টেবিলটি আপডেট করে নি। আমি কেন খুঁজে পেয়েছি - আমার SETকরছিল REPLACEএবং আমি কলামে একটি নির্দিষ্ট স্ট্রিং ফাঁকা করার চেষ্টা করছিলাম - ওরাকল ট্রিটসকে ''নাল হিসাবে দেখায় , এবং এই ক্ষেত্রটি শূন্য করা যায়নি। আমি ভেবেছিলাম বাক্যবিন্যাসটি আসলটির পরিবর্তে কেবলমাত্র একটি টেম্প টেবিল আপডেট করছে তবে আমি ভুল ছিল।
vapcguy

2

টেবিল 2 এর জন্য ডেস্কের পরিবর্তে বিবরণ ব্যবহার করা ,

update
  table1
set
  value = (select code from table2 where description = table1.value)
where
  exists (select 1 from table2 where description = table1.value)
  and
  table1.updatetype = 'blah'
;

আপনি কেন টেবিল 2 এ দুটি পৃথক প্রশ্ন ছুড়তে চান
জিতেন্দ্র ভিসপুট

2

এটি সূক্ষ্ম ওরাকল কাজ করে

merge into table1 t1
using (select * from table2) t2
on (t1.empid = t2.empid)
when matched then update set t1.salary = t2.salary

এর শেষে কমা যুক্ত করে একাধিক বৈশিষ্ট্য সেট করতে পারেন। ইউজারআইএনফো ( ) নামক একটি টেবিল থেকে তাদের নামটি পুনরুদ্ধার করার t1.First_Name = t2.FirstName, t1.Last_Name = t2.LastNameজন্য "ইউজারনেম" কলামে ( t1.UserName = t2.UserName) ব্যবহার করার পরে আমার একটি টেবিলের উপর কাজ করা দরকার select * from UserInfo) t2। ডাটাবেসটি এমন ছিল যেখানে এটি ব্যবহারকারীর নামটি সর্বত্র ব্যবহারকারীর তথ্য ব্যবহারকারীর তথ্য হিসাবে ব্যবহার করে, সরাসরি টেবিলে ফার্স্টনাম এবং লাস্টনাম রাখার পরিবর্তে। এই যে স্থির!
vapcguy

আপনার উত্তরের পাঁচ বছর আগে কাসনসুইয়ের দেওয়া জবাবটিতে এই উত্তরটি কিছুই যোগ করে না।
ছাগড়া

0
UPDATE table1 t1
SET t1.value = 
    (select t2.CODE from table2 t2 
     where t1.value = t2.DESC) 
WHERE t1.UPDATETYPE='blah';

0
UPDATE IP_ADMISSION_REQUEST ip1
SET IP1.WRIST_BAND_PRINT_STATUS=0
WHERE IP1.IP_ADM_REQ_ID        =
  (SELECT IP.IP_ADM_REQ_ID
  FROM IP_ADMISSION_REQUEST ip
  INNER JOIN VISIT v
  ON ip.ip_visit_id=v.visit_id
  AND v.pat_id     =3702
  ); `enter code here`

0

যেমন সম্পূর্ণতার বিষয়টি, এবং যেহেতু আমরা ওরাকল এর সাথে কথা বলছি, এটি এটিও করতে পারে:

declare
begin
  for sel in (
    select table2.code, table2.desc
    from table1
    join table2 on table1.value = table2.desc
    where table1.updatetype = 'blah'
  ) loop
    update table1 
    set table1.value = sel.code
    where table1.updatetype = 'blah' and table1.value = sel.desc;    
  end loop;
end;
/

1
এটি এটি করতে পারে তবে এটি সম্ভবত সবচেয়ে ধীরতম উপায়।
এপিসি

-1
UPDATE (SELECT T.FIELD A, S.FIELD B
FROM TABLE_T T INNER JOIN TABLE_S S
ON T.ID = S.ID)
SET B = A;

A এবং B টির নাম ক্ষেত্র, আপনাকে টেবিলটি নির্দেশ করার দরকার নেই।


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

1
অবশ্যই, আমি একটি উত্তর দেখেছি যেখানে টেবিলের নাম (টেবিল 1.বি = টেবিল 2.এ) নির্দেশ করে খ = a লেখা হয়েছিল তবে টেবিলটি নির্দেশ করার দরকার নেই।
ড্যান অ্যান্ডারসন

আপনি প্রকৃতপক্ষে দর্শন থেকে ক্ষেত্রগুলি আপডেট করছেন যা টেবিলে ম্যাপ করা হয়। যদি অভ্যন্তরীণ দৃষ্টিভঙ্গি এইচটি করা হয়, তবে "স্ব-ডকুমেন্টিং" সংস্করণটি "সেট এইচবি = হেক্টর" হবে।
sf_jeff

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