programing

Oracle: 테이블이 존재하는 경우

closeapi 2023. 3. 2. 22:16
반응형

Oracle: 테이블이 존재하는 경우

것을 있기를 .IF EXISTS설하하다

특히 MySQL에서 테이블을 드롭하고 싶을 때마다 다음과 같은 작업을 수행합니다.

DROP TABLE IF EXISTS `table_name`;

하면 하지 않는 테이블이 하지 않습니다.DROP에러는 발생하지 않고, 스크립트는 속행할 수 있습니다.

Oracle에도 비슷한 메커니즘이 있습니까?다음 쿼리를 사용하여 테이블이 존재하는지 여부를 확인할 수 있습니다.

SELECT * FROM dba_tables where table_name = 'table_name';

, 이 을 '''로 ''을 합니다.DROP도망치고 있어

가장 효과적이고 최선의 방법은 "table not found" 예외를 검출하는 것입니다.이것에 의해, 테이블이 2회 존재하는지를 확인하는 오버헤드가 회피됩니다.또, 어떠한 다른 이유(중요할 가능성이 있는 경우)에 의해서 DROP 에 장해가 발생해도, 예외는 발신자에게 계속 발생하는 문제에 시달리지 않습니다.

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

ADDENDUM 다른 오브젝트유형에 대응하는 블록은 다음과 같습니다.

순서

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

현재 스키마에 테이블이 있는지 확인하기 위한 것입니다. 테이블이 스키마에 는 ' 스키마'를 사용해야 all_tablesuser_tables을 붙입니다.all_tables.owner = upper('schema_name')

저도 같은 것을 찾고 있었습니다만, 도움이 되는 프로시저를 작성하게 되었습니다.

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;

도움이 되었으면 좋겠다

테이블이 이미 존재하는 경우 테이블을 만드는 전체 코드를 게시하고 싶었을 뿐입니다(제가 아니라 그에게 칭찬합니다).

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;

SQL*PLUS에서는 언제든지 SQLERROR 명령을 사용할 수 있습니다.

WHENEVER SQLERROR CONTINUE NONE
DROP TABLE TABLE_NAME;

WHENEVER SQLERROR EXIT SQL.SQLCODE
DROP TABLE TABLE_NAME;

★★★★★★★★★★★★★★★★ CONTINUE NONE에러가 보고되지만 스크립트는 계속됩니다.★★★★★★★★★★★★★★★★ EXIT SQL.SQLCODE에러가 발생했을 경우 스크립트는 종료됩니다.

참고 항목: SQLERROR 문서

또 다른 방법은 예외를 정의하고 다른 모든 예외가 전파되도록 하는 것입니다.

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;

나는 다음과 같은 경제적 해결책을 선호한다.

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;

한 가지 방법은 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;
/

DBFiddle 데모

oracle에는 'DROP TABLE IF EXISTES'가 없으므로 select 문을 수행해야 합니다.

다음을 시도해 보십시오(저는 oracle 구문에 정통하지 않으므로 변수가 ify인 경우 양해 바랍니다).

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

다음 토막은 나에게 효과가 있었다.

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

또한 DDL을 다시 시작하고 드롭/작성 주기를 최소화하려면 dbms_metadata.get_ddl을 사용하여 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; 이것은 예에 불과합니다.내부에는 DDL 타입, 이름 및 소유자가 변수인 루프가 존재해야 합니다.

이런 블록은 당신에게 유용할 수 있습니다.

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;  

언제든지 스스로 오류를 발견할 수 있습니다.

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

다른 언어의 빈 catch()와 마찬가지로 이를 과도하게 사용하는 것은 잘못된 관행으로 간주됩니다.

안부 전해요
K

아쉽게도 존재하지 않는 경우 드롭, 존재하지 않는 경우 CREATE 등의 기능은 없습니다.

여기에 논리를 포함하기 위해 plsql 스크립트를 작성할 수 있습니다.

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

Oracle Syntax는 별로 좋아하지 않지만 @Erich의 스크립트는 이런 것 같습니다.

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;

테이블과 스키마 소유자를 지정하는 것이 좋습니다.

대소문자를 구분하는 것도 주의해 주세요.(아래의 "위" 절 참조).

TABLE 이외의 장소에서 사용할 수 있다는 것을 보여주기 위해 몇 가지 다른 오브젝트를 넣었습니다.

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

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;  

TABLE의 예를 다음에 나타냅니다.

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

// 이 코드를 실행하면 테이블이 존재하는지 확인하고 나중에 테이블 max를 만듭니다.이것은 단일 컴파일로 동작합니다.

언급URL : https://stackoverflow.com/questions/1799128/oracle-if-table-exists

반응형