2008-10-23 8 views
13

में किसी तालिका नाम के बजाय एक सबक्वायरी का उपयोग करने के लिए मुझे एक अपडेट स्टेटमेंट लिखने की आवश्यकता है जो कई पंक्तियों का उपयोग करता है यह निर्धारित करने के लिए कि कौन सी पंक्तियों को अद्यतन करना है, क्योंकि ओरेकल में, एकाधिक तालिकाओं की अनुमति नहीं है। निम्न क्वेरी एक "ORA-00971: लापता सेट कीवर्ड" वापस आ जाएगी त्रुटिओरेकल अपडेट स्टेटमेंट

UPDATE 
    TABLE1 a, 
    TABLE2 b 
SET 
    a.COL1 = 'VALUE' 
WHERE 
    a.FK = b.PK 
    AND b.COL2 IN ('SET OF VALUES') 

ओरेकल पर अद्यतन बयान वाक्य रचना अवलोकन किया जा रहा है, मैं निम्नलिखित link पाया है, जो दिखाता है कि आप एक के स्थान पर एक सबक्वेरी उपयोग कर सकते हैं तालिका नाम।

जब मैं इस तरह क्वेरी लिखने का प्रयास किया है, मैं एक "ORA-01,779: एक स्तंभ जो एक गैर कुंजी से संरक्षित मेज पर नक्शे संशोधित नहीं कर सकते" मिल गया

UPDATE 
    (
    SELECT 
     a.COL1 
    FROM 
     TABLE1 a, 
     TABLE2 b 
    WHERE 
     a.FK = b.PK 
     AND b.COL2 IN ('SET OF VALUES') 
) update_tbl 
SET 
    update_tbl.COL1 = 'VALUE' 

मैं क्वेरी को फिर से लिखने की थी (शो नीचे) इसके बजाय एक EXISTS कथन का उपयोग करके और यह ठीक काम करता है, लेकिन यह अभी भी जानना चाहेगा कि यह कैसे किया जाता है।

UPDATE 
    TABLE1 update_tbl 
SET 
    update_tbl.COL1 = 'VALUE' 
WHERE 
    EXISTS (
    SELECT 
     1 
    FROM 
     TABLE1 a 
     TABLE2 b 
    WHERE 
     a.FK = b.PK 
     AND b.COL2 IN ('SET OF VALUES') 
     AND update_tbl.PK = a.PK 
) 

धन्यवाद! -Nate

उत्तर

7

एक अन्य विकल्प:

UPDATE TABLE1 a 
SET a.COL1 = 'VALUE' 
WHERE a.FK IN 
(SELECT b.PK FROM TABLE2 b 
    WHERE b.COL2 IN ('SET OF VALUES') 
) 

आपका दूसरे उदाहरण काम करेगा यदि (क) दृश्य शामिल Table1 की घोषित पी:

UPDATE 
    (
    SELECT 
     a.COL1, a.PKCOL 
    FROM 
     TABLE1 a, 
     TABLE2 b 
    WHERE 
     a.FK = b.PK 
     AND b.COL2 IN ('SET OF VALUES') 
) update_tbl 
SET 
    update_tbl.COL1 = 'VALUE' 

... और (ख) Table1। एफके घोषित TABLE2

(घोषित करके मेरा मतलब है कि एक बाधा मौजूद है और एनए ब्लेड)।

0

आपके UPDATE खंड में क्वेरी के परिणाम सेट में प्रत्येक पंक्ति को उस तालिका में एक और केवल एक पंक्ति पर मैप करना होगा, जिसे आप अपडेट करने का प्रयास कर रहे हैं, और इस तरह ओरेकल स्वचालित रूप से अनुसरण कर सकता है। चूंकि क्वेरी वास्तव में एक दृश्य है, इसके बारे में सोचने का एक तरीका यह है कि ओरेकल को लक्ष्य तालिका में वापस देखने में सक्षम होना चाहिए ताकि यह पता चल सके कि कौन सी पंक्ति अपडेट हो।

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

2

जब आप कोई अद्यतन करते हैं तो आप स्पष्ट रूप से सिस्टम को एक नए मान पर मूल्य अपडेट करने के लिए कह सकते हैं - इसे "वाई" और "ज़ेड" दोनों में "एक्स" अपडेट करने के लिए कहने का अर्थ नहीं है। इसलिए, जब आप एक इनलाइन व्यू के परिणाम पर अपडेट का आधार देते हैं तो ओरेकल एक चेक करता है कि संशोधित कॉलम को दो बार अपडेट होने से रोकने के लिए पर्याप्त बाधाएं होती हैं।

आपके मामले में मुझे उम्मीद है कि TABLE2.PK वास्तव में घोषित प्राथमिक कुंजी नहीं है। यदि आप उस कॉलम पर प्राथमिक या अद्वितीय बाधा डालते हैं तो आपको जाना अच्छा होगा।

ओरेकल द्वारा आंतरिक रूप से उपयोग किए जाने वाले अपडेट कार्डिनिटी चेक में शामिल होने के लिए एक अनियंत्रित संकेत है, लेकिन मैं इसका उपयोग करने की सलाह नहीं दूंगा।

इसके लिए एक वर्कअराउंड एक मेर्ज स्टेटमेंट का उपयोग करना है, जो एक ही परीक्षण के अधीन नहीं है।

3

आपके उदाहरण का वाक्यविन्यास ठीक है, लेकिन ओरेकल के लिए आवश्यक है कि सबक्वायरी में प्राथमिक कुंजी शामिल हों। यह एक बहुत ही महत्वपूर्ण सीमा है।

एक संबंधित नोट पर, आप भी कोष्ठक का उपयोग कर सकते हैं, एक में बयान में 2 या अधिक फ़ील्ड का उपयोग करने के रूप में:

UPDATE 
    TABLE1 update_tbl 
SET 
    update_tbl.COL1 = 'VALUE' 
WHERE 
    (update_tbl.PK1, update_tbl.pk2) in(
         select some_field1, some_field2 
         from some_table st 
         where st.some_fields = 'some conditions' 
        ); 
6

मुझे लगता है कि एक अच्छा, जल्दी, लगातार जिस तरह से एक SELECT कथन चालू करने के लिए एक अद्यतन में ROWID के आधार पर अद्यतन करना है।

UPDATE 
    TABLE1 
SET 
    COL1 = 'VALUE' 
WHERE 
    ROWID in 
    (
    SELECT 
     a.rowid 
    FROM 
     TABLE1 a, 
     TABLE2 b 
    WHERE 
     a.FK = b.PK 
     AND b.COL2 IN ('SET OF VALUES') 
    ) 

तो, आपकी आंतरिक क्वेरी पंक्तियों को अद्यतन करने के लिए परिभाषित कर रही है।

1

मैंने पाया मैं यहाँ क्या जरूरत: Useful SQL Commands

मैं
में शामिल होने के एक का परिणाम के साथ एक मेज को अद्यतन करने की जरूरत है मैं सफलता :(

यहाँ बिना ऊपर समाधान की कोशिश की के एक उद्धरण है जिस पृष्ठ पर मैंने
कर्सर का उपयोग करके मैं सफलतापूर्वक कार्य को प्राप्त करने में सक्षम था
मुझे यकीन है कि एक और समाधान है लेकिन यह एक ऐसा काम करता है ...

DECLARE 

/* Output variables to hold the result of the query: */ 
a T1.e%TYPE; 
b T2.f%TYPE; 
c T2.g%TYPE; 

/* Cursor declaration: */ 
CURSOR T1Cursor IS 
    SELECT T1.e, T2.f, T2.g 
    FROM T1, T2 
    WHERE T1.id = T2.id AND T1.e <> T2.f 

FOR UPDATE; 

BEGIN 

    OPEN T1Cursor; 

    LOOP 

    /* Retrieve each row of the result of the above query 
    into PL/SQL variables: */ 
    FETCH T1Cursor INTO a, b; 

    /* If there are no more rows to fetch, exit the loop: */ 
    EXIT WHEN T1Cursor%NOTFOUND; 

    /* Delete the current tuple: */ 
    DELETE FROM T1 WHERE CURRENT OF T1Cursor; 

    /* Insert the reverse tuple: */ 
    INSERT INTO T1 VALUES(b, a); 

    /* Here is my stuff using the variables to update my table */ 
    UPDATE T2 
    SET T2.f = a 
    WHERE T2.id = c; 

    END LOOP; 

    /* Free cursor used by the query. */ 
    CLOSE T1Cursor; 

END; 
. 
run; 


नोट: मत भूलना प्रतिबद्ध करने के लिए ;-)

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