sql - ओरेकल:अगर टेबल मौजूद है




oracle sql-drop (13)

मैं ओरेकल डेटाबेस के लिए कुछ माइग्रेशन स्क्रिप्ट लिख रहा हूं, और उम्मीद कर रहा था कि ओरेकल के पास MySQL के IF EXISTS निर्माण के समान कुछ था।

विशेष रूप से, जब भी मैं MySQL में एक टेबल ड्रॉप करना चाहता हूं, तो मैं कुछ ऐसा करता हूं

DROP TABLE IF EXISTS `table_name`;

इस प्रकार, यदि तालिका मौजूद नहीं है, तो DROP कोई त्रुटि उत्पन्न नहीं करता है, और स्क्रिप्ट जारी रख सकती है।

क्या ओरेकल में एक समान तंत्र है? मुझे एहसास है कि मैं यह जांचने के लिए निम्न क्वेरी का उपयोग कर सकता हूं कि कोई तालिका मौजूद है या नहीं

SELECT * FROM dba_tables where table_name = 'table_name';

लेकिन एक DROP साथ मिलकर बांधने के लिए वाक्यविन्यास मुझे भाग रहा है।


Answers

"तालिका नहीं मिली" अपवाद को पकड़ने का सबसे अच्छा और सबसे प्रभावी तरीका है: यह जांचने के ऊपरी भाग से बचाता है कि तालिका दो बार मौजूद है या नहीं; और समस्या से पीड़ित नहीं है कि यदि डीआरओपी किसी अन्य कारण से विफल रहता है (यह महत्वपूर्ण हो सकता है) अपवाद अभी भी कॉलर को उठाया गया है:

BEGIN
   EXECUTE IMMEDIATE 'DROP TABLE mytable';
EXCEPTION
   WHEN OTHERS THEN
      IF SQLCODE != -942 THEN
         RAISE;
      END IF;
END;

संदर्भ के लिए, यहां अन्य ऑब्जेक्ट प्रकारों के लिए समकक्ष ब्लॉक हैं:

अनुक्रम

BEGIN
  EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -2289 THEN
      RAISE;
    END IF;
END;

राय

BEGIN
  EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -942 THEN
      RAISE;
    END IF;
END;

उत्प्रेरक

BEGIN
  EXECUTE IMMEDIATE 'DROP TRIGGER ' || trigger_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -4080 THEN
      RAISE;
    END IF;
END;

सूची

BEGIN
  EXECUTE IMMEDIATE 'DROP INDEX ' || index_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -1418 THEN
      RAISE;
    END IF;
END;

स्तंभ

BEGIN
  EXECUTE IMMEDIATE 'ALTER TABLE ' || table_name
                || ' DROP COLUMN ' || column_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -904 THEN
      RAISE;
    END IF;
END;

डाटाबेस लिंक

BEGIN
  EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -2024 THEN
      RAISE;
    END IF;
END;

भौतिक दृश्य

BEGIN
  EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || mview_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -12003 THEN
      RAISE;
    END IF;
END;

प्रकार

BEGIN
  EXECUTE IMMEDIATE 'DROP TYPE ' || type_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -4043 THEN
      RAISE;
    END IF;
END;

बाधा

BEGIN
  EXECUTE IMMEDIATE 'ALTER TABLE ' || table_name
            || ' DROP CONSTRAINT ' || constraint_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -2443 THEN
      RAISE;
    END IF;
END;

शेड्यूलर नौकरी

BEGIN
  DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -27475 THEN
      RAISE;
    END IF;
END;

उपयोगकर्ता / स्कीमा

BEGIN
  EXECUTE IMMEDIATE 'DROP USER ' || user_name;
  /* you may or may not want to add CASCADE */
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -1918 THEN
      RAISE;
    END IF;
END;

पैकेज

BEGIN
  EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -4043 THEN
      RAISE;
    END IF;
END;

प्रक्रिया

BEGIN
  EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -4043 THEN
      RAISE;
    END IF;
END;

समारोह

BEGIN
  EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -4043 THEN
      RAISE;
    END IF;
END;

टेबल-स्पेस

BEGIN
  EXECUTE IMMEDIATE 'DROP TABLESPACE' || tablespace_name;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -959 THEN
      RAISE;
    END IF;
END;

मैं टेबल और स्कीमा मालिक निर्दिष्ट करना पसंद करता हूं।

केस संवेदनशीलता के लिए भी देखें। (नीचे "ऊपरी" खंड देखें)।

मैंने यह दिखाने के लिए कुछ अलग-अलग वस्तुओं को फेंक दिया कि टैबलेट के अलावा स्थानों में इसका उपयोग किया जा सकता है।

.............

declare
   v_counter int;
begin
 select count(*) into v_counter from dba_users where upper(username)=upper('UserSchema01');
   if v_counter > 0 then
      execute immediate 'DROP USER UserSchema01 CASCADE';
   end if; 
end;
/



CREATE USER UserSchema01 IDENTIFIED BY pa$$word
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp
  QUOTA UNLIMITED ON users;

grant create session to UserSchema01;  

और एक टेबल उदाहरण:

declare
   v_counter int;
begin
 select count(*) into v_counter from all_tables where upper(TABLE_NAME)=upper('ORDERS') and upper(OWNER)=upper('UserSchema01');
   if v_counter > 0 then
      execute immediate 'DROP TABLE UserSchema01.ORDERS';
   end if; 
end;
/   

आप हमेशा त्रुटि को पकड़ सकते हैं।

begin
execute immediate 'drop table mytable';
exception when others then null;
end;

इसे अन्य भाषाओं में खाली पकड़ () 'es के समान, इसे अधिक उपयोग करने के लिए बुरी आदत माना जाता है।

सादर
कश्मीर


एक तरीका है DBMS_ASSERT.SQL_OBJECT_NAME का उपयोग DBMS_ASSERT.SQL_OBJECT_NAME :

यह फ़ंक्शन सत्यापित करता है कि इनपुट पैरामीटर स्ट्रिंग एक मौजूदा SQL ऑब्जेक्ट का एक योग्य SQL पहचानकर्ता है।

DECLARE
    V_OBJECT_NAME VARCHAR2(30);
BEGIN
   BEGIN
        V_OBJECT_NAME  := DBMS_ASSERT.SQL_OBJECT_NAME('tab1');
        EXECUTE IMMEDIATE 'DROP TABLE tab1';

        EXCEPTION WHEN OTHERS THEN NULL;
   END;
END;
/

डीबीफिल्ड डेमो


सिर्फ एक पूर्ण कोड पोस्ट करना चाहता था जो एक टेबल बनाएगा और इसे छोड़ देगा यदि यह पहले से ही जेफरी के कोड का उपयोग कर मौजूद है (उसे बताओ, मुझे नहीं!)।

BEGIN
    BEGIN
         EXECUTE IMMEDIATE 'DROP TABLE tablename';
    EXCEPTION
         WHEN OTHERS THEN
                IF SQLCODE != -942 THEN
                     RAISE;
                END IF;
    END;

    EXECUTE IMMEDIATE 'CREATE TABLE tablename AS SELECT * FROM sourcetable WHERE 1=0';

END;

मैं इसकी तलाश कर रहा हूं लेकिन मैंने मेरी मदद करने के लिए एक प्रक्रिया लिखना समाप्त कर दिया:

CREATE OR REPLACE PROCEDURE DelObject(ObjName varchar2,ObjType varchar2)
IS
 v_counter number := 0;   
begin    
  if ObjType = 'TABLE' then
    select count(*) into v_counter from user_tables where table_name = upper(ObjName);
    if v_counter > 0 then          
      execute immediate 'drop table ' || ObjName || ' cascade constraints';        
    end if;   
  end if;
  if ObjType = 'PROCEDURE' then
    select count(*) into v_counter from User_Objects where object_type = 'PROCEDURE' and OBJECT_NAME = upper(ObjName);
      if v_counter > 0 then          
        execute immediate 'DROP PROCEDURE ' || ObjName;        
      end if; 
  end if;
  if ObjType = 'FUNCTION' then
    select count(*) into v_counter from User_Objects where object_type = 'FUNCTION' and OBJECT_NAME = upper(ObjName);
      if v_counter > 0 then          
        execute immediate 'DROP FUNCTION ' || ObjName;        
      end if; 
  end if;
  if ObjType = 'TRIGGER' then
    select count(*) into v_counter from User_Triggers where TRIGGER_NAME = upper(ObjName);
      if v_counter > 0 then          
        execute immediate 'DROP TRIGGER ' || ObjName;
      end if; 
  end if;
  if ObjType = 'VIEW' then
    select count(*) into v_counter from User_Views where VIEW_NAME = upper(ObjName);
      if v_counter > 0 then          
        execute immediate 'DROP VIEW ' || ObjName;        
      end if; 
  end if;
  if ObjType = 'SEQUENCE' then
    select count(*) into v_counter from user_sequences where sequence_name = upper(ObjName);
      if v_counter > 0 then          
        execute immediate 'DROP SEQUENCE ' || ObjName;        
      end if; 
  end if;
end;

उम्मीद है की यह मदद करेगा


और यदि आप इसे पुनः दर्ज करने और ड्रॉप / निर्माण चक्र को कम करना चाहते हैं, तो आप dbms_metadata.get_ddl का उपयोग करके डीडीएल को कैश कर सकते हैं और इस तरह के निर्माण का उपयोग करके सबकुछ फिर से बना सकते हैं: declare v_ddl varchar2(4000); begin select dbms_metadata.get_ddl('TABLE','DEPT','SCOTT') into v_ddl from dual; [COMPARE CACHED DDL AND EXECUTE IF NO MATCH] exception when others then if sqlcode = -31603 then [GET AND EXECUTE CACHED DDL] else raise; end if; end; declare v_ddl varchar2(4000); begin select dbms_metadata.get_ddl('TABLE','DEPT','SCOTT') into v_ddl from dual; [COMPARE CACHED DDL AND EXECUTE IF NO MATCH] exception when others then if sqlcode = -31603 then [GET AND EXECUTE CACHED DDL] else raise; end if; end; यह सिर्फ एक नमूना है, डीडीएल प्रकार, नाम और मालिक चर के साथ एक लूप होना चाहिए।


BEGIN
   EXECUTE IMMEDIATE 'DROP TABLE "IMS"."MAX" ';
EXCEPTION
   WHEN OTHERS THEN
      IF SQLCODE != -942 THEN
         RAISE;
          END IF;
         EXECUTE IMMEDIATE ' 
  CREATE TABLE "IMS"."MAX" 
   (    "ID" NUMBER NOT NULL ENABLE, 
    "NAME" VARCHAR2(20 BYTE), 
     CONSTRAINT "MAX_PK" PRIMARY KEY ("ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSAUX"  ENABLE
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSAUX"  ';


END;

// इस कोड को करने से, यह जांचता है कि तालिका मौजूद है और बाद में यह तालिका अधिकतम बनाता है। यह बस एकल संकलन में काम करता है


ओरेकल में कोई 'ड्रोप टेबल' एक्सस्ट्स 'नहीं है, आपको चयन कथन करना होगा।

इसे आज़माएं (मैं ऑरैकल सिंटैक्स पर नहीं हूं, इसलिए यदि मेरे चर इफ़ी हैं, तो कृपया मुझे माफ़ कर दें):

declare @count int
select @count=count(*) from all_tables where table_name='Table_name';
if @count>0
BEGIN
    DROP TABLE tableName;
END

अफसोस की बात है, अगर मौजूद है तो ड्रॉप जैसी कोई चीज नहीं है, या अगर पूर्ववत नहीं है तो ऐसी कोई चीज नहीं है

आप तर्क को शामिल करने के लिए एक plsql स्क्रिप्ट लिख सकते हैं।

http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm

मैं ओरेकल सिंटेक्स में ज्यादा नहीं हूं, लेकिन मुझे लगता है कि @ एरिच की लिपि इस तरह कुछ होगी।

declare 
cant integer
begin
select into cant count(*) from dba_tables where table_name='Table_name';
if count>0 then
BEGIN
    DROP TABLE tableName;
END IF;
END;

एसक्यूएल * प्लस के साथ आप WHENEVER SQLERROR कमांड का भी उपयोग कर सकते हैं:

WHENEVER SQLERROR CONTINUE NONE
DROP TABLE TABLE_NAME;

WHENEVER SQLERROR EXIT SQL.SQLCODE
DROP TABLE TABLE_NAME;

CONTINUE NONE साथ CONTINUE NONE त्रुटि रिपोर्ट CONTINUE NONE की जाती है, लेकिन स्क्रिप्ट जारी रहेगी। EXIT SQL.SQLCODE के साथ स्क्रिप्ट को किसी त्रुटि के मामले में समाप्त कर दिया जाएगा।

यह भी देखें: जब भी SQLERROR डॉक्स


मैं निम्नलिखित आर्थिक समाधान पसंद करते हैं

BEGIN
    FOR i IN (SELECT NULL FROM USER_OBJECTS WHERE OBJECT_TYPE = 'TABLE' AND OBJECT_NAME = 'TABLE_NAME') LOOP
            EXECUTE IMMEDIATE 'DROP TABLE TABLE_NAME';
    END LOOP;
END;

    select object_name from user_objects where object_type='TABLE';

---------------- या ------------------

    select * from tab;

---------------- या ------------------

    select table_name from user_tables;




sql oracle sql-drop