在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
条件的语法,我认为哪个也是写的。
请建议我......
答案 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是失败代码。
这很简单,如果在运行查询时出现异常,它将被抑制。并且您可以将其用于SQL
或Oracle
。
答案 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;