2010-01-08 16 views
8

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

पल इस मूल अनुप्रयोग में दो कदम, 'सी' में लिखा में किया जाता है पर:

SELECT idnext FROM mytable; 
    UPDATE mytable SET idnext = idnext + 1; 

जाहिर है वहाँ एक रेस स्थिति यहाँ है, कई प्रक्रियाओं एक ही बात करते हैं।

संपादित करें: महत्वपूर्ण कोरक्विससाइट: मैं डेटाबेस/फ़ील्ड परिभाषा को स्पर्श नहीं कर सकता, यह नियम अनुक्रम से बाहर है।

हम perl में पुनः लिख रहे हैं, और मैं वही काम करना चाहता हूं, लेकिन बेहतर। एक परमाणु समाधान अच्छा होगा। दुर्भाग्य से मेरे एसक्यूएल कौशल सीमित हैं, इसलिए मैं सामूहिक ज्ञान में बदल रहा हूं :-)

+0

मैं अद्यतन एसक्यूएल केवल पर्याप्त सही लग रहा है 'अद्यतन mytable सेट idnext = idnext + 1,' आपको सर्वर पर idnext पढ़ने की आवश्यकता क्यों है? –

उत्तर

9

इस विशेष मामले में, अनुक्रम का उल्लेख सही समाधान है। लेकिन अगर कुछ भविष्य स्थिति में आप दोनों अद्यतन कुछ करने की जरूरत है और एक ही बयान में कोई मान है, तो आप RETURNING खंड का उपयोग कर सकते हैं:

UPDATE atable SET foo = do_something_with(foo) RETURNING foo INTO ? 

बुला कोड PL/SQL है, की जगह? एक स्थानीय पीएल/एसक्यूएल चर के साथ; अन्यथा आप इसे अपने प्रोग्राम में आउटपुट पैरामीटर के रूप में बांध सकते हैं।

संपादित करें: जब से तुम पर्ल उल्लेख किया है, कुछ इस तरह (untested) काम करने के लिए चाहिए:

my $sth = $dbh->prepare('UPDATE mytable SET idnext = idnext + 1 returning idnext into ?'); 
my $idnext; 
$sth->bind_param_inout(1, \$idnext, 8); 
$sth->execute; # now $idnext should contain the value 

DBI देखें।

+0

तो मेरा बयान इस तरह दिखना चाहिए: (?) अपडेट करें mytable SET idnext = idnext + 1 वापसी रद्द करें; –

+0

मेरा कॉलिंग कोड perl है। मैंने एसक्यूएल कमांडलाइन पर यह कोशिश की, लेकिन इसमें सिंटैक्स समस्याएं हैं: अपडेट करें mytable SET idnext = idnext + 1 वापसी idnext –

+0

INTO भाग आवश्यक है। और यह एक कमांड लाइन पर काम नहीं करेगा (जहां तक ​​मुझे पता है)। – Dan

0

अनुक्रम नौकरी करेगा, उदाहरण पर देखें Oracle sequences

4

sequence का उपयोग क्यों नहीं करें?

अनुक्रम एक बार बनाएं, जो कुछ भी मूल्य के साथ शुरू आप चाहते हैं का उपयोग कर:

SELECT mysequence.NEXTVAL 
    INTO idnext 
    FROM DUAL; 

:

CREATE SEQUENCE mysequence 
    START WITH 1 
    MAXVALUE 999999999999999999999999999 
    MINVALUE 1 
    NOCYCLE 
    NOCACHE 
    NOORDER; 

तो रनटाइम पर अपने आवेदन कोड में आप इस कथन अगले मूल्य प्राप्त करने के लिए उपयोग कर सकते अपडेट: अनुक्रम का उपयोग करना पसंदीदा तरीका होगा, लेकिन चूंकि आप डेटाबेस को नहीं बदल सकते हैं, इसलिए मैं सहमत हूं कि रिटर्निंग का उपयोग करने से आपकी स्थिति के लिए काम करना चाहिए:

UPDATE mytable 
     SET idnext = idnext + 1 
RETURNING idnext 
    INTO mylocalvariable; 
+0

मुझे मौजूदा फ़ील्ड का उपयोग करना है और इसकी परिभाषा को छू नहीं सकता है। –

2

अद्यतन विवरण के लिए चयन का उपयोग करें। यह रिकॉर्ड करने के लिए पारस्परिक रूप से विशिष्ट अधिकारों की गारंटी देता:

"SELECT FOR UPDATE;

+0

क्या आप एक पूर्ण उदाहरण प्रदान कर सकते हैं? –

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