嘿,我是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;
如果我单独运行这两个代码块,但是当我一起运行它们时它不起作用。有没有办法在一个脚本中组合这些类型的查询?
由于
答案 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
/
这将尝试删除表格,但如果它不能继续,然后尝试创建表格。如果由于某种原因失败,则脚本将失败。