2014-09-19 63 views
0

我对Oracle很新颖。下面是我想一个复杂的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 

我认为把一个伪代码有助于了解正是我试图完成。 任何帮助将不胜感激。

回答

0

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

你可以,因此,创建临时表的过程外(但我立足我的数据类型的columns--您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 
); 

你会然后使用该临时表在你的代码就像你会永久表(所以在你的selectorder by是没有意义的)

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类型参数SYS_REFCURSOR并使用SELECT语句打开游标,调用程序可以从中读取该语句。

+0

谢谢贾斯汀,这对我有用!但是,它并不需要我创建全局临时表。我不确定这是否也是临时表,但我有如下所示的代码。谢谢你的帮助! TempTable as(SELECT a.Id,a.Due_Date,a.Start_Date,a.End_Date,LAG(a.Id,1)over(按Id排序)为Prev_Id, LAG(a.End_Date,1)over a.End_Date)as Prev_End_Dat FROM myTable a order by a.Id) – 2014-09-22 21:47:38

+0

@KunalNair - 我不确定您是否在说您创建了一个正在执行“CREATE TABLE AS SELECT”的永久表,或者您是否在说你在'SELECT'语句中使用了'WITH'子句。 “WITH”子句将是一种完全合理的方式,可以在不使用内联视图的情况下构建单个“SELECT”语句。永久性表格在多用户环境中会有问题。 – 2014-09-22 22:09:23

+0

我使用了WITH语句。 – 2014-09-23 16:31:54