2010-10-25 13 views
20

संभव डुप्लिकेट:
Oracle: how to UPSERT (update or insert into a table?)Oracle SQL: अद्यतन करता है, तो किसी और मौजूद है सम्मिलित

हाय,

मैं जो में एक रिकॉर्ड है, तो यह पहले से ही संशोधित किया जाना है एक मेज है मौजूद है एक नया रिकॉर्ड डालना है। ओरेकल एसक्यूएल does not को IF EXISTS स्वीकार करते हैं, अन्यथा मैं एक if - update - else - insert क्वेरी किया होता। मैंने MERGE पर देखा है लेकिन यह केवल कई तालिकाओं के लिए काम करता है। मैं क्या करूं?

उत्तर

-1

this सवाल को देखें आप/Upsert का उपयोग Oracle में आदेश मर्ज करना चाहते हैं। अन्यथा, बस कर एक count(1) पहले और उसके बाद सम्मिलित या अपडेट किए जाने तय करने के बाद क्लाइंट की तरफ आपकी समस्या का समाधान।

+1

आपको कम से सही नहीं हो सकता है; ओरेकल 9i के बाद से ओरेकल ने मेर्ज स्टेटमेंट का समर्थन किया है। –

+1

एक्स-रेफ अच्छा है; यह आप जो कहते हैं, उसके विपरीत है। मेरा -1 नहीं, लेकिन मैं कम से कम इसके साथ सहानुभूति व्यक्त करता हूं। –

2

तरह से मैं हमेशा यह करना (डेटा संभालने, हटाए जाने के लिए कभी नहीं किया गया है केवल डाला) सबसे पहले एक insert करते हैं, अगर यह एक अद्वितीय बाधा उल्लंघन के साथ विफल हो तो आप को पता पंक्ति है

  • है वहाँ,
  • फिर एक update

ऐसे हाइबरनेट के रूप में दुर्भाग्य से कई व्यवस्थाएं सभी डेटाबेस त्रुटियों (जैसे अद्वितीय बाधा उल्लंघन) अप्राप्य शर्तों के रूप में इलाज करते हैं, तो यह हमेशा आसान नहीं है।

कि के रूप में भले ही शून्य रिटर्न तुम सिर्फ एक select count(*) .. where .. ऐसा नहीं कर सकते (हाइबरनेट में समाधान सिर्फ इस एक insert आदेश पर अमल करने के लिए एक नया सत्र/लेन-देन को खोलने के लिए है।), और इसलिए आप एक insert करने के लिए चुनते हैं, समय के बीच आप select और बाकी insert कोई हो सकता है insert एड पंक्ति करते हैं और इसलिए अपने insert असफल हो जायेगी।

+0

यहां तक ​​कि केवल बाधा डालने के साथ ही, दो लेनदेन का उपयोग करके विशिष्टता अपवादों का कारण बन सकता है यदि एकाधिक अद्यतनकर्ता तालिका में लिख रहे हैं। –

+0

डेविड मैन, मुझे खेद है कि मुझे समझ में नहीं आया; कृपया स्पष्ट करें। –

+0

हाय एड्रियन, मैं बस ऐसे मामले के बारे में सोच रहा हूं जहां अद्यतन स्टेटमेंट केवल तभी मान्य है जब INSERT के प्रयास के बाद डेटा नहीं बदला गया है, और इसमें कई प्रक्रियाएं शामिल हैं जो आवेषण और अपडेट कर रही हैं। जब तक कि तालिका में सभी आवेषण और अपडेट सिंक्रनाइज़ नहीं होते हैं, कभी-कभी अद्यतन सफल हो सकता है और कभी-कभी यह प्रक्रियाओं को अंतःस्थापित करने के तरीके के आधार पर विफल हो सकती है। ऐसा तब तक मुझे एक कोने का मामला लग रहा था जब तक कि मुझे अद्यतन करने की आवश्यकता नहीं थी, जो कि केवल तब मान्य हैं जब अंतिम पढ़ने के बाद से डेटा की स्थिति अभी भी वही है। –

51

मर्ज "एकाधिक तालिकाओं" की जरूरत नहीं है, लेकिन यह स्रोत के रूप में एक प्रश्न की जरूरत है। कुछ इस तरह काम करना चाहिए:

BEGIN 
    INSERT INTO mytable (id, name) VALUES (1, 'x'); 
EXCEPTION 
    WHEN DUP_VAL_ON_INDEX THEN 
    UPDATE mytable 
    SET name = 'x' 
    WHERE id = 1; 
END; 
+1

+1 मुझे 'मेर्ज' निर्देश के बारे में पता नहीं है, लेकिन अपवाद के लिए 'DUP_VAL_ON_INDEX' हैंडलिंग के लिए, यह निश्चित रूप से एक अच्छा समाधान है, यह जानकर कि ओरेकल अपवाद हैंडलिंग नियमित रूप से इस तरह के व्यवहार के लिए उपयोग की जाती है! =) –

+1

+1; यह ध्यान दिया जाना चाहिए कि वैकल्पिक समाधान आमतौर पर बहुत कम कुशल होता है। – DCookie

2

आप SQL%ROWCOUNT ओरेकल चर इस्तेमाल कर सकते हैं:

MERGE INTO mytable d 
USING (SELECT 1 id, 'x' name from dual) s 
ON (d.id = s.id) 
WHEN MATCHED THEN UPDATE SET d.name = s.name 
WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name); 

वैकल्पिक रूप से आप/एसक्यूएल पी एल में यह कर सकते हैं

UPDATE table1 
    SET field2 = value2, 
     field3 = value3 
WHERE field1 = value1; 

IF (SQL%ROWCOUNT = 0) THEN 

    INSERT INTO table (field1, field2, field3) 
    VALUES (value1, value2, value3); 

END IF; 

यह आसान होगा सिर्फ निर्धारित करें कि आपका प्राथमिक कुंजी (यानी field1) अपना महत्व होता है और फिर एक डालने प्रदर्शन या तदनुसार अद्यतन करें। यही है, यदि आप संग्रहीत प्रक्रिया के लिए मानकों के रूप में कहा मानों का उपयोग करते हैं।

+8

यदि आपके पास एक से अधिक सत्र लेखन एक साथ हैं, तो आप स्थिति में भाग सकते हैं कि 'अपडेट' शून्य पंक्तियों को छूता है ताकि आप मान सकें कि कोई पंक्ति नहीं है और 'डालने' की आवश्यकता है, लेकिन उस समय किसी ने ' सम्मिलित करें 'तो आपका' डालने 'एक अद्वितीय बाधा उल्लंघन के साथ विफल रहता है। यही कारण है कि 'डालने' (और अनन्य बाधा उल्लंघन को पकड़ना) करना महत्वपूर्ण है, फिर 'अपडेट करें', दूसरी तरफ नहीं। –

4
merge into MY_TABLE tgt 
using (select [expressions] 
     from dual) src 
    on (src.key_condition = tgt.key_condition) 
when matched then 
    update tgt 
     set tgt.column1 = src.column1 [,...] 
when not matched then 
    insert into tgt 
     ([list of columns]) 
    values 
     (src.column1 [,...]); 
0

कोर्ट तरह :)

DECLARE 
    rt_mytable mytable%ROWTYPE; 
    CURSOR update_mytable_cursor(p_rt_mytable IN mytable%ROWTYPE) IS 
    SELECT * 
    FROM mytable 
    WHERE ID = p_rt_mytable.ID 
    FOR UPDATE; 
BEGIN 
    rt_mytable.ID := 1; 
    rt_mytable.NAME := 'x'; 
    INSERT INTO mytable VALUES (rt_mytable); 
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN 
    <<update_mytable>> 
    FOR i IN update_mytable_cursor(rt_mytable) LOOP 
    UPDATE mytable SET  
     NAME = p_rt_mytable.NAME 
    WHERE CURRENT OF update_mytable_cursor; 
    END LOOP update_mytable; 
END; 
+0

इस बारे में कुछ खास नहीं है क्योंकि इसका मूल सिद्धांत पहले ही पोस्ट किया गया था। बस मज़ा के लिए :) –

+0

"एचसी" का क्या अर्थ है? –

+0

इसका मतलब है कट्टर –

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