在Oracle中创建检查表之前是否存在检查表

时间:2013-03-26 06:32:24

标签: oracle if-statement

在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条件的语法,我认为哪个也是写的。 请建议我......

9 个答案:

答案 0 :(得分:24)

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

答案 1 :(得分:1)

请尝试:

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;

答案 2 :(得分:1)

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;

答案 3 :(得分:1)

我知道这个话题有点陈旧,但我认为我做了一些可能对某人有用的事情,所以我发布了它。

我将这个帖子的答案汇编成一个程序:

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

我知道两次传递表名有点多余,但我认为这是最简单的。

希望有人发现以上有用: - )。

答案 4 :(得分:1)

我的解决方案是在线程中汇编最佳创意,稍作改进。 我使用专用过程(@Tomasz Borowiec)来促进重用,并使用异常处理(@Tobias Twardon)来减少代码并在过程中删除冗余表名。

DECLARE

    PROCEDURE create_table_if_doesnt_exist(
        p_create_table_query VARCHAR2
    ) IS
    BEGIN
        EXECUTE IMMEDIATE 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;
/

答案 5 :(得分:1)

-检查特定模式下的表:

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;

答案 6 :(得分:0)

任何在创建之前依赖测试的解决方案都可能会遇到“竞争”情况,在该情况下,另一个过程会在您测试不存在的表与创建表之间创建表。 -我知道的要点。

答案 7 :(得分:0)

嗯,已经提供了很多答案,很多答案也很有意义。

有人提到这只是警告,而有些人则给出了禁用警告的临时方法。一切都会起作用,但是当数据库中的事务数量很高时 会增加风险

我今天遇到了类似情况,这是 非常简单的查询 ,我想出了...

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是失败代码。

这很简单,如果在运行查询时出现异常,它将被抑制。并且您可以将其用于SQLOracle

答案 8 :(得分:0)

也不需要申报和计数。

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;
相关问题