2015-05-29 128 views
3

我需要创建一个表,如果它不存在,并且它创建时向它添加一行。创建表如果它不存在,并创建后输入一行

我新的Oracle和PL/SQL,所以我基本上需要下面的T-SQL的等价物:

IF OBJECT_ID('my_table', 'U') IS NULL BEGIN CREATE TABLE my_table(id numeric(38,0), date datetime)
INSERT INTO my_table VALUES (NULL, 0) END

+3

此要求背后的原因是什么?这是一个家庭作业问题吗?通常,您不应该在PL/SQL中创建表 - 表是永久对象,应该创建一次,然后在任何代码中使用。如果你在一张临时存放数据的表格后面,那么考虑创建一个全局临时表格(Global Temporary Table,GTT),它是一个永久性表格,允许数据按照每个会话临时存储(即会话2看不到会话1存储的GTT中的数据,反之亦然)。 – Boneist

+0

它就像你使用的是sybase语法 – Moudiz

回答

0

您可以使用NOT EXISTS用select语句:

IF NOT EXISTS(SELECT 1 FROM my_table) THEN 
CREATE TABLE my_table(id NUMBER, date date); 
COMMIT; 
INSERT INTO my_table(id, date) values (NULL, O); 
COMMIT; 
END IF; 

UPDATE

根据评论,我不能使用Exist directl y在PL/SQL中。因此,这是另一种方式来做到这一点:

begin 
    select case 
      when exists(select 1 
         from my_table) 
      then 1 
      else 0 
     end into l_exists 
    from dual; 

    if (l_exists = 1) 
    then 
    -- anything 
    else 
    EXECUTE IMMEDIATE 'CREATE TABLE my_table(id NUMBER, date date)'; 
    EXECUTE IMMEDIATE 'INSERT INTO my_table(id, date) values (NULL, O)'; 
    end if; 
end; 
+0

不,你不能;你不能在普通的SQL中使用'IF',但是如果你能'SELECT 1 FROM my_table'仍然会得到ORA-00942。如果你在PL/SQL块中完成了这个工作,你必须进行动态创建和插入,并且你不能直接在PL/SQL中使用'exists',只能在SQL中使用。 –

+0

@AlexPoole谢谢。我提出了另一种方式来做到这一点。 – Hawk

+0

嗯。你尝试过你的解决方案吗? :)由于@AlexPoole表示你的脚本不能编译,因为MY_TABLE不存在。 IF部分不是编译,而是由于不同的原因,你忘记了声明等。你需要通过从user_tables,all_objects或类似的东西中选择来检查表的存在。所以NOT EXISTS不是用于查询,而是用于测试对象存在。 –

4
,如果你想查询表创建

DECLARE count NUMBER; 
BEGIN 
count := 0; 
SELECT COUNT(1) INTO count from user_tables WHERE table_name= 'MY_TABLE'; 
IF COL_COUNT = 0 THEN 
EXECUTE IMMEDIATE 'create table ....'; 
END IF; 
END; 
/

支票用于DML。请注意,您必须sepcify你的PK列和值

DECLARE count NUMBER; 
BEGIN 
count := 0; 
SELECT COUNT(1) INTO count from MY_TABLE WHERE id= 0 and name='Something'; 
IF COL_COUNT = 0 THEN 
EXECUTE IMMEDIATE 'insert into MY_TABLE (id,name) values(0,''something'') '; 
END IF; 
END; 
/

也注意到我recomand当你插入表

+0

也许值得一提的是插入也必须动态完成? (并且将'col_count' - 你的名字不一致! - 设为零)是多余的。) –

+0

@AlexPoole好吗我添加了一个插入检查 – Moudiz

+0

我的意思是在同一个块中,在动态创建之后。在单独的块中不太合理;如果选择工作(因为表格现在存在),那么插入不需要是动态的。但OP似乎希望将创建/插入作为一步;所以你应该在第一个块中同时执行两个“立即执行”语句? –

2

另一种方法是使用异常的逻辑来指定列。我根据甲骨文规则

declare 
    eAlreadyExists exception; 
    pragma exception_init(eAlreadyExists, -00955); 
begin 
    execute immediate 'CREATE TABLE my_table(id number, dateof date)'; 
    execute immediate 'INSERT INTO my_table VALUES (NULL, sysdate)'; 
    exception when eAlreadyExists then 
     null; 
end; 

改变字段名和类型,但可能它不是创建表动态

+0

*但可能是它不是一个好主意动态创建表*我同意,但只是好奇,你的解释是为什么不动态创建表? – mmmmmpie

0

在我看来,你不应该动态创建的对象是个好主意。在实施之前,你应该考虑你的设计。

无论如何,如果你真的想这样做,这样,那么你需要编程做在使用EXECUTE 立即PL/SQL(AB)。

但是,如果您想用单行创建表ta一次,我宁愿CTAScreate table as select。例如,

SQL> CREATE TABLE t AS SELECT 1 id, SYSDATE dt FROM DUAL; 

Table created. 

SQL> SELECT * FROM t; 

     ID DT 
---------- --------- 
     1 29-MAY-15 

SQL> 

该表是永久创建的。

如果您正在寻找临时表,您可以使用它临时存储会话特定数据,然后查看creating Global temporary table

从技术文档,

使用CREATE GLOBAL TEMPORARY TABLE语句来创建临时表 。 ON COMMIT子句指示表中的数据是否为 特定交易(默认)或会话特定

相关问题