Oracle使用动态sql制作本地表?

问题描述 投票:0回答:1

如何在Oracle中使用本地临时表或使用动态SQL的替代方法?

在SQL Server中,从名为dbo.2019的表中选择所有列到名为x的本地临时表中:

CREATE TABLE #x (a int)

DECLARE @FY varchar(4) = Year(date())

EXEC ('SELECT * into #x FROM dbo.'+@FY)

之所以这样做,是因为我想使用各种信息(除年份之外,例如来自其他表或其他任何表的值)来构建非常复杂的查询,而无需很多奇怪的子查询。

SQL Server的局限性是您必须首先创建临时表,或者必须使用全局表,否则人们可能会覆盖它们。

sql sql-server oracle dynamic-sql
1个回答
0
投票

您知道,Oracle <> MS SQL Server。后者大量使用临时表。 Oracle-通常/通常是不需要的。

但是,对于您的特定问题(“非常复杂的查询”之类的东西),这可能不是一个坏主意。根据您的Oracle数据库版本,有全局临时表(和-在最新版本中为私有)。它们如何工作?您一次创建它们并使用多次,这意味着您不应动态创建它们。尽管许多用户可以同时使用它们,但是存储在其中的数据仅对您可见。此外,在整个会话期间(如果您选择使用on commit preserve rows选项创建数据)或在事务处理期间[on commit delete rows)都保留数据。

例如:

SQL> create global temporary table gtt_test
  2    (id     number,
  3     name   varchar2(20))
  4  on commit delete rows;

Table created.

SQL>

您可以将它们编入索引:

SQL> create index i1_gtt on gtt_test (id);

Index created.

SQL>

然后做任何你想做的事。一旦您的会话(或交易)结束,吹气!它们为空,不是数据永久存储在其中。如果明天您必须做同样的工作,桌子仍然在这里等着您。没有[[dynamic创建/删除/创建/删除(或您认为应该做的任何事情)。

因此:只需创建一次,即可在需要时使用。


如果它是[[必须动态的,请当心:

SQL> declare 2 l_cnt number; 3 begin 4 -- check whether table already exists 5 select count(*) 6 into l_Cnt 7 from user_tables 8 where table_name = 'TEST'; 9 10 -- yes, it exists - drop it first 11 if l_cnt = 1 then 12 execute immediate 'drop table test'; 13 end if; 14 -- now create it 15 execute immediate 'create table test (id number, name varchar2(20))'; 16 17 -- insert some rows 18 insert into test (id, name) values (1, 'Littlefoot'); 19 end; 20 / insert into test (id, name) values (1, 'Littlefoot'); * ERROR at line 18: ORA-06550: line 18, column 15: PL/SQL: ORA-00942: table or view does not exist ORA-06550: line 18, column 3: PL/SQL: SQL Statement ignored SQL> 尽管我首先检查表是否存在(以便先删除它,然后重新创建它),但整个PL / SQL块都失败了,因为我正在尝试使用尚不存在的表(在编译时)。

因此,如果我想使用该test表,则在同一个PL / SQL块中的任何操作也应变为动态,这是

可怕的

:编写丑陋,难以调试,当心单引号问题...您真的想要避免这种情况。

再次:我建议您不要动态地这样做。

© www.soinside.com 2019 - 2024. All rights reserved.