2010-04-11 11 views
16

ओरेकल 8 डीबी का उपयोग करने वाले मेरे एप्लिकेशन के लिए, मैं ट्रिगर्स, अनुक्रम इत्यादि जैसी चीजों को सेट करने के लिए एक SQL स्क्रिप्ट प्रदान कर रहा हूं, जिसे कॉपी और चिपकाया जा सकता है एसक्यूएल * प्लस में चिपकाया जा सकता है। मैं स्क्रिप्ट को किसी त्रुटि के साथ नहीं रोकना चाहूंगा यदि एक अनुक्रम जिसे मैं बनाने की कोशिश कर रहा हूं, पहले से मौजूद है। एक ट्रिगर के लिए इसे "ट्रिगर बनाएं या बदलें ..." का उपयोग करके आसानी से किया जा सकता है, लेकिन अनुक्रम के लिए यह काम नहीं करता है। मैंने यह भी कोशिश की कि "अगर मेरा अस्तित्व मौजूद नहीं है तो अनुक्रम बनाएं ..." लेकिन यह भी नहीं था। क्या कोई विकल्प है?क्या ओरेकल एसक्यूएल में "अगर अस्तित्व नहीं बना है ..." जैसा कुछ है?

वैकल्पिक रूप से, यदि यह संभव नहीं है, तो "अनुक्रम अनुक्रम" करने का कोई तरीका है "एसक्यूएल बिना * प्लस स्क्रिप्ट निरस्त किया जा रहा है, तो mysequence मौजूद नहीं है

+0

Oracle में एक AutoIncrement समारोह की उपस्थिति कैसे मदद मिलेगी का समाधान क्या स्पष्ट रूप से एक स्रोत नियंत्रण/विन्यास प्रबंधन मुद्दा है? – APC

+0

@APC: क्षमा करें, मुझे समझ में नहीं आता है। क्या आप इसे अधिक विस्तार से समझा सकते हैं? मेरा मतलब यह था कि: मुझे एक टेबल की आवश्यकता है जो एक ऑटोइनक्रिकमेंट फ़ील्ड है। उदाहरण में एसक्यूएल सर्वर मैं कॉलम को एक ऑटोइनक फ़ील्ड के रूप में परिभाषित करता हूं, और मैं कर रहा हूं। ओरेकल में मुझे एक संख्यात्मक कॉलम, फिर एक अनुक्रम बनाने की आवश्यकता है, फिर मेरे कॉलम को भरने के लिए उस अनुक्रम का उपयोग करने के लिए एक ट्रिगर। यह मेरे लिए बहुत कठोर प्रतीत नहीं होता है। – Timo

+0

मेरा मुद्दा यह है कि, यदि आपके पास उचित स्कीमा प्रबंधन था, तो आपको अनुक्रम के पूर्व अस्तित्व को संभालने की आवश्यकता नहीं होगी क्योंकि आप केवल डेटाबेस के विरुद्ध एक CREATE SEQUENCE कथन चला रहे होंगे जहां आप जानते थे कि अनुक्रम मौजूद नहीं था। – APC

उत्तर

7

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

WHENEVER SQLERROR CONTINUE 
-- create sequences here, ignoring errors 
WHENEVER SQLERROR EXIT SQL.SQLCODE 

ध्यान रखें अगर वहाँ अन्य त्रुटियों (अनुमति नहीं है समस्याओं, वाक्य रचना विफलताओं, आदि) बनाने के अनुक्रम बयान में वे

+0

अच्छा, मुझे उस निर्देश के बारे में पता नहीं था। धन्यवाद! – Timo

1

आप देखने के लिए कि अनुक्रम बनाया जा रहा पहले से ही मौजूद है या नहीं user_sequence तालिका की जांच कर सकते

इसी प्रकार के davek के समाधान:। विचार है , किसी भी अनुक्रम बनाने से पहले, अनुक्रम ड्रॉप करें और इसे बनाएं, सभी गतिशील एसक्यूएल में, एक फ़ंक्शन बनाएं, और कहें कि आपको 10 अनुक्रम बनाने की आवश्यकता है, तो f nction देखभाल करें ...

function crt_seq(p_seq_name varchar2) 
return boolean 
begin 
    for i in (select 1 from user_sequence where sequence_name = upper(p_seq_name)) 
    loop 
    ---- Already exists. You can drop and recreate or return false to error out 
    execute immediate 'drop sequence '||p_seq_name; 
    execute immediate 'create sequence '||p_seq_name||' start with 1 increment 
        by 1 nocache'; 
    end loop; 
    return true; 
exception 
when others then 
    return false; 
end; 

आप अन्य सभी विकल्पों को पैरामीट्रिज कर सकते हैं और आपके लिए अनुक्रम बनाने के लिए एक विस्तृत कार्य कर सकते हैं।

+0

मुझे स्वीकार करना होगा I ओरेकल के लिए इस तरह की नौसिखिया हूँ, मुझे यह भी नहीं पता कि उस समारोह को परिभाषित करने के लिए और इसे मेरी एसक्यूएल स्क्रिप्ट से कैसे कॉल करें, लेकिन ओरेकल पर मेरी पुस्तकें पहले से ही मेरी मेज पर हैं, इसलिए जब आपका ज्ञान अधिक ज्ञान होगा तो आपका जवाब शायद मेरी मदद करेगा :-) धन्यवाद। – Timo

+1

चेतावनी: अगर आपके पास अनुक्रम का उपयोग कर कोड (जैसे संकुल) है, तो यह उन्हें अमान्य कर देगा। यदि आप इस कोड को चलाते हैं तो उन पैकेजों का उपयोग करने पर आपके पास लॉकिंग समस्याएं भी हो सकती हैं। ओह, और यदि अनुक्रम पहले से मौजूद है और इसका उपयोग किया गया है, तो आपको डुप्लिकेट मान मिलेंगे। –

+0

ठीक है, धन्यवाद। – Timo

11
DECLARE 
    v_dummy NUMBER; 
BEGIN 
    -- try to find sequence in data dictionary 
    SELECT 1 
    INTO v_dummy 
    FROM user_sequences 
    WHERE sequence_name = 'MY_SEQUENCE_NAME'; 

    -- if sequence found, do nothing 
EXCEPTION 
    WHEN no_data_found THEN 
    -- sequence not found, create it 
    EXECUTE IMMEDIATE 'create sequence my_sequence_name'; 
END; 
+1

अच्छा प्रयास करें, लेकिन इस रूप में, यह काम नहीं करेगा। आपके पास अपरकेस-लोअरकेस समस्या है: जहां होना चाहिए sequence_name = 'MY_SEQUENCE_NAME'; –

+0

@ammoQ अब इसे सही किया गया है, धन्यवाद। – jva

+0

मैंने 'user_sequences' होने के लिए तालिका का नाम बदल दिया – Shawn

4

नजरअंदाज कर दिया जाएगा मुझे पसंद है:

DECLARE 
    C NUMBER; 
BEGIN 
    SELECT COUNT(*) INTO C 
    FROM ALL_TRIGGERS 
    WHERE OWNER = 'YOUROWNER' 
    AND TRIGGER_NAME = 'YOURTRIGGER'; 

    IF (C = 0) THEN 
    EXECUTE IMMEDIATE ' 
     CREATE TRIGGER "YOUROWNER"."YOURTRIGGER" 
     blah blah blah your trigger blah blah 
    '; 
    END IF; 
END; 
/
+0

ट्रिगर MyTriggerName का उपयोग करने के लिए उपयोग करना बहुत आसान है MyTable पर इन्टरनेट ..... – Oscar

0
DECLARE 
    lsSeqName VARCHAR2(32 CHAR) := UPPER('MY_SEQUENCE_NAME'); 
    lnSeqCount NUMBER; 
BEGIN 
    -- try to find sequence in data dictionary 
    SELECT count(1) 
    INTO lnSeqCount 
    FROM user_sequences 
    WHERE UPPER(sequence_name) = lsSeqName; 
    -- if sequence not found, create it 
    IF lnSeqCount = 0 THEN 
    EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || lsSeqName || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER'; 
    END IF; 
END; 
/

या

-- helper method 
PROCEDURE createSeqIfNotExists (
    isSeqName VARCHAR2 
) IS 
    lnSeqCount NUMBER; 
BEGIN 
    -- try to find sequence in data dictionary 
    SELECT count(1) 
    INTO lnSeqCount 
    FROM user_sequences 
    WHERE UPPER(sequence_name) = UPPER(isSeqName); 
    -- if sequence not found, create it 
    IF lnSeqCount = 0 THEN 
    EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || UPPER(isSeqName) || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER'; 
    END IF; 
END createSeqIfNotExists; 

-- call method 
BEGIN 
    createSeqIfNotExists('MY_SEQUENCE_NAME'); 
END; 
/