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

在Oracle存储过程中使用临时表,oracle,stored-procedures,Oracle,Stored Procedures,我对甲骨文还很陌生。下面是我在复杂的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 b

我对甲骨文还很陌生。下面是我在复杂的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
我认为,编写一个伪代码将有助于准确理解我试图实现的目标。
非常感谢您的帮助。

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

因此,您可以在您的过程之外创建一个临时表——我的数据类型基于列的名称——然而,UPDATE语句意味着至少id、end_date和prev_id必须是varchar2列

然后在代码中使用临时表,就像使用永久表一样,因此select中的order 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中很少使用临时表。在本例中,我只将您的规则作为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语句将结果返回给调用方。存储过程可以有一个SYS_REFCURSOR类型的OUT参数,并使用SELECT语句打开一个游标,然后调用者可以从中获取。

谢谢Justin,这对我很有用!但是,它不需要我创建一个全局临时表。我不确定这是否也是一个临时表,但我有如下所示的代码。谢谢你的帮助!可诱惑资产选择a.Id、a.Due\u Date、a.Start\u Date、a.End\u Date、LAGa.Id、1 over order by Id作为上一个Id、LAGa.End\u Date、,1在a.End_日期之前的订单,作为myTable a中a.End_日期之前的订单。Id@KunalNair-我不确定您是说您创建了一个永久表,并将CREATETABLE作为SELECT,还是说您在SELECT语句中使用了WITH子句。WITH子句是构造单个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);