在oracle sql中组合块查询和常规查询

时间:2017-03-13 13:58:50

标签: sql oracle dynamic codeblocks

嘿,我是Oracle SQL的新手,但我经常使用PostGreSQL和SQL Server。我目前正在尝试运行一个查询,每次运行查询时都会实现一个表。实际的应用程序更复杂,但这是一般的想法:

declare
  v_exists number:=0;
BEGIN

    select count(1)
    into v_exists
    from all_tables
    where table_name = 'FFF';

    if v_exists >0 then 
      EXECUTE IMMEDIATE 'DROP TABLE FFF';
      dbms_output.put_line('Table dropped');
    end if;

END;
/


create table fff as 
  select *
  from my_table;

如果我单独运行这两个代码块,但是当我一起运行它们时它不起作用。有没有办法在一个脚本中组合这些类型的查询?

由于

3 个答案:

答案 0 :(得分:3)

这是一种在SQL Server(也可能是PostgreSQL)中常见但在Oracle中被认为是反模式的模式,Oracle提供了更好的数据集处理方式,而不是动态执行DDL。

一种方法是使用PL / SQL集合来缓存内存中的数据。这在数据量很小时是合适的,因为集合存储在会话存储器中。 Find out more

另一种方法是全局临时表,它是具有瞬态数据的永久结构(仅限于事务或会话的范围)。 Find out more

企业版附带了将结果集固定在内存中的功能;当我们想要跨多个会话共享结果集时,这很有用,并且结果集的生命周期相对较长(即缓慢变化的参考数据)。 Find out more

另一种也许是最好的方法是编写有效的查询,以避免缓存的需要。 DDL是一种昂贵的操作,它将风险和复杂性引入应用程序。做事最具表现力的方式通常是避免这样做。

答案 1 :(得分:0)

尝试将第二个作为动态SQL:

declare
  v_exists number := 0;
BEGIN

    select count(1)
    into v_exists
    from all_tables
    where table_name = 'FFF';

    if v_exists >0 then 
      EXECUTE IMMEDIATE 'DROP TABLE FFF';
      dbms_output.put_line('Table dropped');
    end if;

    EXECUTE IMMEDIATE 'create table fff as select * from my_table';
END;
/

答案 2 :(得分:0)

另一种选择是SQLPLUS中的脚本;

WHENEVER SQLERROR CONTINUE

DROP TABLE fff
/

WHENEVER SQLERROR EXIT FAILURE

CREATE TABLE fff
AS SELECT * FROM my_table
/

这将尝试删除表格,但如果它不能继续,然后尝试创建表格。如果由于某种原因失败,则脚本将失败。