복붙노트

[SQL] 오라클은 다음과 같은 경우 테이블 존재

SQL

오라클은 다음과 같은 경우 테이블 존재

나는 Oracle 데이터베이스에 대한 몇 가지 이주 스크립트를 쓰고 있어요, 그리고 오라클의 MySQL의 IF 비슷한 구조를 EXISTS 있었다 기대했다.

내가 MySQL의에서 테이블을 드롭 할 때마다 특히, 내가 좋아하는 뭔가를 할

DROP TABLE IF EXISTS `table_name`;

테이블이 존재하지 않는 경우이 방법은, 드롭 오류를 생성하지 않으며, 스크립트 계속할 수 있습니다.

오라클은 유사한 메커니즘이 있습니까? 나는 테이블이 존재인지 아닌지 내가 확인하려면 다음 쿼리를 사용할 수 있습니다 실현

SELECT * FROM dba_tables where table_name = 'table_name';

그러나 DROP과 그 함께 묶는 구문은 저를 탈출한다.

해결법

  1. ==============================

    1.가장 좋고 가장 효율적인 방법은 예외 "을 (를) 찾을 수 없습니다 테이블"잡을 것입니다 :이 테이블이 두 번있는 경우 체크의 오버 헤드를 피할 수를; 그리고 DROP (즉 중요 할 수 있음) 다른 이유로 실패 할 경우 예외가 여전히 호출에 발생하는 문제에서 고통을하지 않습니다

    가장 좋고 가장 효율적인 방법은 예외 "을 (를) 찾을 수 없습니다 테이블"잡을 것입니다 :이 테이블이 두 번있는 경우 체크의 오버 헤드를 피할 수를; 그리고 DROP (즉 중요 할 수 있음) 다른 이유로 실패 할 경우 예외가 여전히 호출에 발생하는 문제에서 고통을하지 않습니다

    BEGIN
       EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
    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 AND SQLCODE != -942 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 AND SQLCODE != -942 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;
    

    동의어

    BEGIN
      EXECUTE IMMEDIATE 'DROP SYNONYM ' || synonym_name;
    EXCEPTION
      WHEN OTHERS THEN
        IF SQLCODE != -1434 THEN
          RAISE;
        END IF;
    END;
    
  2. ==============================

    2.

    declare
       c int;
    begin
       select count(*) into c from user_tables where table_name = upper('table_name');
       if c = 1 then
          execute immediate 'drop table table_name';
       end if;
    end;
    

    즉, 현재 스키마의 테이블이 존재하는지 여부를 확인하기 위해입니다. 주어진 테이블이 이미 다른 스키마에 존재하는지 여부를 확인하는 대신 USER_TABLES의 ALL_TABLES를 사용하고 조건 all_tables.owner = 상단 ( 'SCHEMA_NAME')를 추가해야 할 것

  3. ==============================

    3.저도 같은 찾고있다 그러나 나는 저를 도와 절차를 작성 결국 :

    저도 같은 찾고있다 그러나 나는 저를 도와 절차를 작성 결국 :

    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;
    

    도움이 되었기를 바랍니다

  4. ==============================

    4.단지 테이블을 만들고 이미 제프리의 코드를 사용하여 존재하는 경우 드롭하는 전체 코드를 게시하고 싶어 (그에게 명성을 나하지!).

    단지 테이블을 만들고 이미 제프리의 코드를 사용하여 존재하는 경우 드롭하는 전체 코드를 게시하고 싶어 (그에게 명성을 나하지!).

    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;
    
  5. ==============================

    5.SQL로 * PLUS 당신은 또한 WHENEVER SQLERROR 명령을 사용할 수 있습니다 :

    SQL로 * PLUS 당신은 또한 WHENEVER SQLERROR 명령을 사용할 수 있습니다 :

    WHENEVER SQLERROR CONTINUE NONE
    DROP TABLE TABLE_NAME;
    
    WHENEVER SQLERROR EXIT SQL.SQLCODE
    DROP TABLE TABLE_NAME;
    

    NONE을 계속하지에 오류가보고되고 있지만, 스크립트가 계속됩니다. EXIT의 SQL.SQLCODE으로 스크립트 오류의 경우에 종료됩니다.

    또한 참조 : WHENEVER SQLERROR 문서

  6. ==============================

    6.더 오라클의 'DROP TABLE IF가 존재하지 않는'있다, 당신은 선택 성명을해야 할 것입니다.

    더 오라클의 'DROP TABLE IF가 존재하지 않는'있다, 당신은 선택 성명을해야 할 것입니다.

    (난 내 변수 쓸어을 경우 그래서, 용서해주십시오, 오라클 구문에 최대 아니에요)이 시도 :

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

    7.한 가지 방법은 사용 DBMS_ASSERT.SQL_OBJECT_NAME이다 :

    한 가지 방법은 사용 DBMS_ASSERT.SQL_OBJECT_NAME이다 :

    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;
    /
    

    DB 휘티 d 혀라도

  8. ==============================

    8.나는 경제적 인 솔루션을 다음과 선호

    나는 경제적 인 솔루션을 다음과 선호

    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;
    
  9. ==============================

    9.또 다른 방법은 예외를 정의하는 것입니다 만 다른 모든 전파시키는 그 예외를 잡을 수있어.

    또 다른 방법은 예외를 정의하는 것입니다 만 다른 모든 전파시키는 그 예외를 잡을 수있어.

    Declare
       eTableDoesNotExist Exception;
       PRAGMA EXCEPTION_INIT(eTableDoesNotExist, -942);
    Begin
       EXECUTE IMMEDIATE ('DROP TABLE myschema.mytable');
    Exception
       When eTableDoesNotExist Then
          DBMS_Output.Put_Line('Table already does not exist.');
    End;
    
  10. ==============================

    10.존재, 또는 IF NOT의 존재를 만드는 경우 슬프게도 더, 드롭 같은 건 없다

    존재, 또는 IF NOT의 존재를 만드는 경우 슬프게도 더, 드롭 같은 건 없다

    당신은 거기에 논리를 포함하는 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;
    
  11. ==============================

    11.당신은 항상 오류 자신을 잡을 수 있습니다.

    당신은 항상 오류 자신을 잡을 수 있습니다.

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

    그것은이를 남용하는 나쁜 사례로 간주되고, 유사한 ') (다른 언어 ES를 캐치 비어 있습니다.

    문안 인사 케이

  12. ==============================

    12.나는 테이블 및 스키마 소유자를 지정하는 것을 선호합니다.

    나는 테이블 및 스키마 소유자를 지정하는 것을 선호합니다.

    대소 문자 구분에주의뿐만 아니라. (아래의 "위"절 참조).

    나는 테이블 이외의 장소에서 사용할 수있다 쇼에서 다른 개체의 몇 가지를 던졌다.

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

    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;
    /   
    
  13. ==============================

    13.

    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;
    

    // 테이블이 존재하는 경우, 검사를이 코드를 수행하고 나중에는 테이블 최대를 만듭니다. 이것은 단순히 하나의 컴파일에서 작동

  14. ==============================

    14.당신이 만들고 싶어 그리고 그것은이 같은 구조를 사용하여 모든 것을 만들 다시 DBMS_METADATA.GET_DDL 등을 사용하여 DDL을 캐시 할 수, 입력이 가능한 재 드롭 생성 / 사이클을 최소화 :       알리다        v_ddl의 VARCHAR2 (4000);       시작        DBMS_METADATA.GET_DDL ( '표를', 'DEPT', 'SCOTT')를 선택 이중에서 v_ddl에;        [IF NO MATCH 캐시 DDL을 비교해 EXECUTE]       다음 예외 다른 사람        다음은 SQLCODE = -31603 경우         [GET 및 캐시 DDL을 EXECUTE]        그밖에         올리다;        종료면;       종료; 이건 그냥 샘플입니다, DDL 유형, 이름과 소유자 인 변수와 루프 내부가 있어야한다.

    당신이 만들고 싶어 그리고 그것은이 같은 구조를 사용하여 모든 것을 만들 다시 DBMS_METADATA.GET_DDL 등을 사용하여 DDL을 캐시 할 수, 입력이 가능한 재 드롭 생성 / 사이클을 최소화 :       알리다        v_ddl의 VARCHAR2 (4000);       시작        DBMS_METADATA.GET_DDL ( '표를', 'DEPT', 'SCOTT')를 선택 이중에서 v_ddl에;        [IF NO MATCH 캐시 DDL을 비교해 EXECUTE]       다음 예외 다른 사람        다음은 SQLCODE = -31603 경우         [GET 및 캐시 DDL을 EXECUTE]        그밖에         올리다;        종료면;       종료; 이건 그냥 샘플입니다, DDL 유형, 이름과 소유자 인 변수와 루프 내부가 있어야한다.

  15. ==============================

    15.이 같은 블록은 당신에게 도움이 될 수 있습니다.

    이 같은 블록은 당신에게 도움이 될 수 있습니다.

    DECLARE
        table_exist INT;
    
    BEGIN
        SELECT Count(*)
        INTO   table_exist
        FROM   dba_tables
        WHERE  owner = 'SCHEMA_NAME' 
        AND table_name = 'EMPLOYEE_TABLE';
    
        IF table_exist = 1 THEN
          EXECUTE IMMEDIATE 'drop table EMPLOYEE_TABLE';
        END IF;
    END;  
    
  16. from https://stackoverflow.com/questions/1799128/oracle-if-table-exists by cc-by-sa and MIT license