2013-07-17 7 views
10

अपडेट नहीं करें क्या ऑरैकल डालने और हटाने के लिए विलय का उपयोग करने का कोई तरीका है लेकिन अद्यतन नहीं है?ओरेकल एसक्यूएल डालने और हटाने के लिए मर्ज करें लेकिन

मेरे पास एक तालिका है जो किसी अन्य तालिका में एक पंक्ति से संबंधित मानों का एक सेट दर्शाती है। मैं उन सभी को हटाकर और नए सेट को वापस जोड़कर, या चुनिंदा रूप से कुछ हटाने और दूसरों को जोड़कर मूल्यों का सेट बदल सकता हूं, लेकिन यदि संभव हो तो मुझे इसे एक कथन बनाने में दिलचस्पी है।

यहां अपडेट के साथ एक कामकाजी उदाहरण है। इस काम को करने के लिए, मुझे dummy जोड़ना पड़ा ताकि अपडेट करने के लिए एक कॉलम उपलब्ध हो जो on स्थिति में नहीं था। अद्यतन करने के लिए एक डमी कॉलम के बिना केवल हटाने और डालने का कोई तरीका है?

on स्थिति से कोई कॉलम update set स्थिति में हो सकता है भले ही यह वास्तव में अपडेट नहीं किया गया हो।

create table every_value (the_value varchar2(32)); 
create table paired_value (the_id number, a_value varchar2(32) , dummy number default 0); 
-- the_id is a foreign_key to a row in another table 

insert into every_value (the_value) values ('aaa'); 
insert into every_value (the_value) values ('abc'); 
insert into every_value (the_value) values ('ace'); 
insert into every_value (the_value) values ('adg'); 
insert into every_value (the_value) values ('aei'); 
insert into every_value (the_value) values ('afk'); 

-- pair ace and afk with id 3 
merge into paired_value p using every_value e 
on (p.the_id = 3 and p.a_value = e.the_value) 
when matched then update set dummy=dummy+1 
delete where a_value not in ('ace','afk') 
when not matched then insert (the_id,a_value) 
values (3,e.the_value) 
where e.the_value in ('ace','afk'); 

-- pair ace and aei with id 3 
-- should remove afk, add aei, do nothing with ace 
merge into paired_value p using every_value e 
on (p.the_id = 3 and p.a_value = e.the_value) 
when matched then update set dummy = dummy+1 
delete where a_value not in ('ace','aei') 
when not matched then insert (the_id,a_value) 
values (3,e.the_value) 
where e.the_value in ('ace','aei'); 

-- pair aaa and adg with id 4 
merge into paired_value p using every_value e 
on (p.the_id = 4 and p.a_value = e.the_value) 
when matched then update set dummy = dummy+1 
delete where a_value not in ('aaa','adg') 
when not matched then insert (the_id,a_value) 
values (4,e.the_value) 
where e.the_value in ('aaa','adg'); 

select * from paired_value; 

मैं Oracle 10g में यह करने की कोशिश की और इस sqlfiddle, ओरेकल 11g के साथ, है।

उत्तर

15

नहीं, आप उन पंक्तियों को हटा नहीं सकते जिन्हें मर्ज कमांड द्वारा अपडेट नहीं किया गया है। जबकि populating या इसे अद्यतन करने http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm

एक तालिका में हटाएं where_clause साफ करने के लिए डेटा निर्दिष्ट करें:
यहाँ प्रलेखन है। इस खंड से प्रभावित एकमात्र पंक्तियां गंतव्य तालिका में उन पंक्तियों को मर्ज ऑपरेशन द्वारा अपडेट की गई हैं। हटाएं जहां स्थिति अद्यतन मूल्य का मूल्यांकन करती है, मूल मूल्य जो अद्यतन सेट द्वारा मूल्यांकन किया गया था ... जहां स्थिति। यदि गंतव्य तालिका की एक पंक्ति DELETE स्थिति को पूरा करती है लेकिन ऑन क्लॉज, द्वारा परिभाषित शामिल में शामिल नहीं है तो इसे हटाया नहीं गया है। लक्ष्य तालिका पर परिभाषित कोई भी हटाए गए ट्रिगर्स प्रत्येक पंक्ति हटाने के लिए सक्रिय किए जाएंगे।

इसका मतलब है कि पंक्तियों को अपडेट किया जाना चाहिए। Hovewer, आप कहां खंड के रूप में आप के बाद का उपयोग कर रहे DELETE

when matched then update set dummy=dummy 
    where a_value not in ('ace','afk') 
delete 
    where a_value not in ('ace','afk') 
+0

मुझे यकीन था कि डमी कॉलम होने से कोई बेहतर तरीका नहीं था, लेकिन मैं इसके लिए सिर्फ एक डमी कॉलम नहीं जोड़ूंगा। ओह अच्छा। – drawnonward

1

सभी पंक्तियों को अद्यतन करने, के बाद अद्यतन ही उपयोग की जरूरत नहीं है मैं मिल गया है आप खुद के लिए स्तंभ सेट कर सकते हैं:

MERGE ... 
WHEN MATCHED THEN 
    UPDATE SET a_value = a_value WHERE a_value not in ('ace','afk') 
    DELETE WHERE a_value not in ('ace','afk') 

यह डमी कॉलम की आवश्यकता को अस्वीकार करता है।

+0

आपकी स्थिति में as_value है? यह कॉलम 11 जी में मेरे लिए काम नहीं करता है अगर कॉलम ऑन कंडीशन में है, तो मुझे "ऑन क्लॉज में संदर्भित कॉलम अपडेट नहीं किया जा सकता" त्रुटि मिलती है, भले ही अद्यतन खुद को मूल्य निर्धारित कर रहा हो। – Marquez

+0

यह सही है। प्रति ऑर्केकल प्रलेखन आप एक खंड को अद्यतन नहीं कर सकते जो कि ऑन क्लॉज का हिस्सा है। यदि आप इसके बारे में सोचते हैं, तो यह समझ में आता है। लेकिन आप अपडेट में एक अलग गैर-डमी कॉलम का उपयोग कर सकते हैं; कोशिश किए बिना मुझे पता नहीं है कि डिलीट क्लॉज अभी भी एक ही त्रुटि को ट्रिगर करेगा या नहीं? जैसे SET b_value = b_value जहां a_value में नहीं है ('ace', 'afk') हटाएं जहां a_value ('ace', 'afk') में नहीं है। – datico

संबंधित मुद्दे