codememo

Oracle에서 테이블을 생성하기 전에 테이블 존재 여부를 확인합니다.

tipmemo 2023. 3. 29. 21:33
반응형

Oracle에서 테이블을 생성하기 전에 테이블 존재 여부를 확인합니다.

Oracle에서 만들기 전에 테이블이 존재하는지 확인하려고 합니다.Stackoverflow 등의 투고 대부분을 검색합니다.몇 가지 질문을 찾았지만 나에게는 효과가 없었다.

IF((SELECT count(*) FROM dba_tables where table_name = 'EMPLOYEE') <= 0)
THEN
create table EMPLOYEE
(
ID NUMBER(3),
NAME VARCHAR2(30) NOT NULL
)
END IF;

그러면 오류가 발생합니다.

Error: ORA-00900: invalid SQL statement
SQLState:  42000
ErrorCode: 900
Position: 1

의 구문을 검색합니다.IF조건, 어느쪽도 쓰기라고 생각합니다.제안해 주세요...

Rene도 코멘트했듯이 먼저 체크하고 표를 작성하는 것은 매우 드문 일입니다.메서드에 따라 실행 중인 코드를 사용하려면 다음과 같이 하십시오.

declare
nCount NUMBER;
v_sql LONG;

begin
SELECT count(*) into nCount FROM dba_tables where table_name = 'EMPLOYEE';
IF(nCount <= 0)
THEN
v_sql:='
create table EMPLOYEE
(
ID NUMBER(3),
NAME VARCHAR2(30) NOT NULL
)';
execute immediate v_sql;

END IF;
end;

하지만 저는 예외에 주목하여 불필요한 코드 행을 절약하고 싶습니다.

declare
v_sql LONG;
begin

v_sql:='create table EMPLOYEE
  (
  ID NUMBER(3),
  NAME VARCHAR2(30) NOT NULL
  )';
execute immediate v_sql;

EXCEPTION
    WHEN OTHERS THEN
      IF SQLCODE = -955 THEN
        NULL; -- suppresses ORA-00955 exception
      ELSE
         RAISE;
      END IF;
END; 
/

이 주제가 좀 오래된 건 알지만 누군가에게 도움이 될 만한 일을 한 것 같아서 올립니다.

이 스레드의 답변에서 제시된 내용을 절차로 정리했습니다.

CREATE OR REPLACE PROCEDURE create_table_if_doesnt_exist(
  p_table_name VARCHAR2,
  create_table_query VARCHAR2
) AUTHID CURRENT_USER IS
  n NUMBER;
BEGIN
  SELECT COUNT(*) INTO n FROM user_tables WHERE table_name = UPPER(p_table_name);
  IF (n = 0) THEN
    EXECUTE IMMEDIATE create_table_query;
  END IF;
END;

그런 다음 다음과 같은 방법으로 사용할 수 있습니다.

call create_table_if_doesnt_exist('my_table', 'CREATE TABLE my_table (
        id NUMBER(19) NOT NULL PRIMARY KEY,
        text VARCHAR2(4000),
        modified_time TIMESTAMP
  )'
);

테이블 이름을 두 번 넘기는 게 좀 번거롭긴 하지만 그게 여기서 가장 쉬운 것 같아

누군가가 위의 도움이 되기를 바랍니다. :-)

시험해 보세요:

SET SERVEROUTPUT ON
DECLARE
v_emp int:=0;
BEGIN
  SELECT count(*) into v_emp FROM dba_tables where table_name = 'EMPLOYEE'; 

  if v_emp<=0 then
     EXECUTE IMMEDIATE 'create table EMPLOYEE ( ID NUMBER(3), NAME VARCHAR2(30) NOT NULL)';
  end if;
END;
declare n number(10);

begin
   select count(*) into n from tab where tname='TEST';

   if (n = 0) then 
      execute immediate 
      'create table TEST ( ID NUMBER(3), NAME VARCHAR2 (30) NOT NULL)';
   end if;
end;

나의 솔루션은 약간의 개선과 함께 최고의 아이디어를 스레드에 정리하는 것입니다.전용 프로시저(@Tomasz Borowiec)와 예외 처리(@Tobias Twardon)를 모두 사용하여 코드를 줄이고 프로시저에서 중복된 테이블 이름을 제거합니다.

DECLARE

    PROCEDURE create_table_if_doesnt_exist(
        p_create_table_query VARCHAR2
    ) IS
    BEGIN
        EXECUTE IMMEDIATE p_create_table_query;
    EXCEPTION
        WHEN OTHERS THEN
        -- suppresses "name is already being used" exception
        IF SQLCODE = -955 THEN
            NULL; 
        END IF;
    END;

BEGIN
    create_table_if_doesnt_exist('
        CREATE TABLE "MY_TABLE" (
            "ID" NUMBER(19) NOT NULL PRIMARY KEY,
            "TEXT" VARCHAR2(4000),
            "MOD_TIME" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ');
END;
/

작성 전 테스트에 의존하는 솔루션은 존재하지 않는 테이블을 다른 프로세스로 작성하는 '경합' 상태에 빠질 수 있습니다.- 마이너 포인트입니다.

-- 특정 스키마 내의 테이블을 확인합니다.

declare n number(10);

begin
    Select count(*) into n  from SYS.All_All_Tables where owner = 'MYSCHEMA' and TABLE_NAME =  'EMPLOYEE';

   if (n = 0) then 
     execute immediate 
     'create table MYSCHEMA.EMPLOYEE ( ID NUMBER(3), NAME VARCHAR2(30) NOT NULL)';      
   end if;
end;

음, 이미 많은 답변이 제공되었고 많은 답변이 타당합니다.

일부에서는 경고일 뿐이고 일부는 경고를 비활성화할 수 있는 임시 방법을 제공한다고 언급했습니다.이 모든 것은 작동하지만 DB의 트랜잭션 수가 많을 경우 위험이 가중됩니다.

오늘 비슷한 상황을 만났는데, 여기 제가 생각해낸 아주 간단한 질문이 있습니다.

declare
begin
  execute immediate '
    create table "TBL" ("ID" number not null)';
  exception when others then
    if SQLCODE = -955 then null; else raise; end if;
end;
/

955는 장애 코드입니다.

이것은 간단합니다. 쿼리를 실행하는 동안 예외가 발생하면 억제됩니다.그리고 같은 것을 사용할 수 있습니다.SQL또는Oracle.

신고 및 카운트도 적용할 필요가 없습니다.

begin
for rec in (select 1 from user_tables where table_name = 'YOUR_TABLE')
-- or
-- for rec in (select 1 from all_tables where table_name = 'YOUR_TABLE' and owner = 'YOU')
loop
    execute immediate 'create table your_table as (f1 char(1))';
end loop;
end;
/

좋은 모드 생성 체크 기능이 될 것입니다.

create or replace function this_object_exists (p_obj_name user_objects.object_name%type) return boolean
is
begin
   for rec in (select 1 from user_objects where object_name = upper(p_obj_name))
   loop
        return true;
   end loop;
   return false;
end this_object_exists;

그래서 체크에 코드를 사용한다.

. . . .
인덱스 파티션 테이블 서브파티션 순서 테이블 칸막이
절차. LOB 파티션 LOB 인덱스 서브파티션
패키지 포장체 활자체 트리거
색인 테이블 보다 기능.
동의어 유형 ...
begin
if not this_object_exists('your_table') then
    execute immediate 'create table your_table as (f1 char(1))';
end if;
end;

또는

begin
if this_object_exists('your_table') then
    execute immediate 'drop table your_table';
end if;
execute immediate 'create table your_table as (f1 char(1))';
end;

언급URL : https://stackoverflow.com/questions/15630771/check-table-exist-or-not-before-create-it-in-oracle

반응형