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
'codememo' 카테고리의 다른 글
| POST를 angularj로 전송하려면 어떻게 해야 하나요? (0) | 2023.03.29 |
|---|---|
| 리액트 JS에서 jQuery UI를 사용하는 방법 (0) | 2023.03.29 |
| 각도 JS의 이중과 단일 곱슬 가새의 차이? (0) | 2023.03.29 |
| 클래스 A가 복수의 JSON 필드를 선언합니다. (0) | 2023.03.29 |
| MVC4에서 Json 문자열을 JsonResult로 출력하려면 어떻게 해야 합니까? (0) | 2023.03.29 |