在Oracle存储过程中使用临时表

时间:2014-09-19 21:35:25

标签: oracle stored-procedures

我对Oracle很陌生。这是我在复杂的oracle存储过程中尝试做的事情:

-- Create a temp table from the below query. Lets call it MyTempTable
    SELECT  a.Id, a.Due_Date, a.Start_Date, a.End_Date,LAG(a.Id,1) over (order by Id) as Prev_Id, 
            LAG(a.End_Date,1) over (order by a.End_Date) as Prev_End_Dat
    FROM  myTable a
    order by a.Id

-- On MyTempTable
    update myTempTable
    set a.Id = ' '
    and a.End_Date = ''
    where a.Id <> a.Prev_Id

-- Once i apply this rule, I need to do the following
    select * from MyTempTable

我认为放置伪代码有助于准确理解我要完成的任务。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

假设您是Oracle新手但熟悉其他数据库,Oracle中的临时表与许多其他数据库中的临时表非常不同。 Oracle中的临时表定义是全局的 - 您的临时表必须在过程之外创建,并且对于每个人都可见,就像永久表一样。但是,您插入的数据是当前会话或事务的本地数据(取决于表的定义)。

因此,您可以在程序之外创建一个临时表(我的数据类型基于列的名称 - 您的UPDATE语句暗示,至少idend_dateprev_id必须为varchar2列)

CREATE GLOBAL TEMPORARY TABLE myTempTable( 
  id            integer,
  due_date      date,
  start_date    date,
  end_date      date,
  prev_id       integer,
  prev_end_date date
);

然后,您可以在代码中使用该临时表,就像使用永久表一样(因此order by中的select毫无意义)

INSERT INTO myTempTable( id, due_date, start_date, end_date, prev_id, prev_end_date )
  SELECT  a.Id, a.Due_Date, a.Start_Date, a.End_Date,
          LAG(a.Id,1) over (order by Id) as Prev_Id, 
          LAG(a.End_Date,1) over (order by a.End_Date) as Prev_End_Dat
    FROM  myTable a;

那会有用。但是在Oracle中做这件事并不常见。在Oracle中使用临时表非常罕见。在这种情况下,我只是将您的规则作为SELECT语句

的一部分来实现
SELECT (case when id != prev_id
              then ' '
              else id 
          end) id,
       (case when id != prev_id 
             then null
             else end_date
         end) end_date,
       due_date,
       start_date,
       prev_id,
       prev_end_date
  FROM (SELECT  a.Id, a.Due_Date, a.Start_Date, a.End_Date,
                LAG(a.Id,1) over (order by Id) as Prev_Id, 
                LAG(a.End_Date,1) over (order by a.End_Date) as Prev_End_Dat
          FROM  myTable a);

还要注意(除非您使用12c的新功能),存储过程不能只运行SELECT语句将结果返回给调用者。存储过程可以具有类型为OUT的{​​{1}}参数,并使用调用者可以从中获取的SYS_REFCURSOR语句打开游标。