2014-09-19 2 views
0

Я довольно новичок в 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 заявления означает, однако, что по крайней мере id, end_date и prev_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); 

Имейте в виду также, что (если вы не используете новые функции 12с), хранимая процедура не может просто запустить SELECT чтобы вернуть результат вызывающему абоненту. Хранимая процедура может иметь параметр OUT типа SYS_REFCURSOR и открыть курсор, используя оператор SELECT, который может вызывать вызывающий.

+0

Спасибо, Джастин, это сработало для меня! Однако мне не потребовалось создать глобальную таблицу temp. Я не уверен, что это тоже временная таблица, но у меня есть код, как показано ниже. Спасибо за вашу помощь! TempTable as (SELECT a.Id, a.Due_Date, a.Start_Date, a.End_Date, LAG (a.Id, 1) over (order by Id) как Prev_Id, LAG (a.End_Date, 1) over (order by a.End_Date) как Prev_End_Dat FROM myTable a order by a.Id) –

+0

@KunalNair - Я не уверен, что вы говорите, вы использовали предложение 'WITH' в инструкции' SELECT'. Предложение 'WITH' было бы вполне разумным способом структурирования одного оператора SELECT без использования встроенного представления. Постоянная таблица будет проблематичной в многопользовательской среде. –

+0

Я использовал инструкцию WITH. –

Смежные вопросы