Вставка набора результатов в таблицу в Oracle - PullRequest
0 голосов
/ 28 июля 2010

Heyho,

Я должен написать процедуру, которая вставляет набор результатов из оператора select в таблицу.Мой коллега сделал что-то подобное, прежде чем копировать значения из одной таблицы в другую.Его утверждение выглядит следующим образом:

CREATE OR REPLACE PROCEDURE Co-Worker(
    pId IN INT
)
AS
BEGIN
    INSERT INTO Table1_PROCESSED
    SELECT * FROM Table1
    WHERE ID = pId;

    DELETE FROM Table1
    WHERE ID = pId;

END Co-Worker;
/

Две таблицы, упомянутые здесь, имеют одинаковую структуру (фактически table1_processed - это просто копия таблицы 1).Поэтому я подумал: «Эй! Я тоже получаю набор результатов из своего выбора! Так почему я просто не настраиваю его, делаю то же самое!»Поэтому я создал свою таблицу следующим образом:

MyTable:
TIMEID (number) | NAME (varchar2 - 128)
-----------------------------------
VALUE       | VALUE
VALUE       | VALUE
VALUE       | VALUE

, а моя процедура выглядит следующим образом:

CREATE OR REPLACE procedure MyProcedure(
pdate in date,
pJobtype in number  default 3,
pTasktype in number default 4,
pJobstatus in number default 1,
pTaskstatus in number default 4
)
AS
    pformateddate date;
BEGIN
    Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
    into pformateddate 
    from dual;
Insert into MyTable (TIMEID, NAME)
Select Function_GETTIMEID(to_date(st, 'DD.MM.YYYY HH24')) TIMEID
       ,to_char(ext) NAME 
from(
    Select to_char(arch_job.exec_start, 'DD.MM.YYYY HH24') st
           ,file.name ext
           , count(file.id) cnt
    from 
         arch_task_file 
             left join file on arch_task_file.File_ID = file.ID
             left join arch_task on arch_task_file.Task_ID = arch_task.ID
             left join arch_job on arch_task.Job_ID = arch_job.ID
    where 
        arch_job.exec_start > pformateddate 
        and arch_job.exec_end <pformateddate + 1 
        and arch_job.jobtype_id = pJobtype 
        and arch_job.jobstatus_id = pJobstatus 
        and arch_task.Tasktype_ID = pTasktype 
        and arch_task.Taskstatus_ID = pTaskstatus
     group by 
         file.name,
           to_char(arch_job.exec_start, 'DD.MM.YYYY HH24'
       )
    );
End MyProcedure;
/

Результат для большого оператора выбора ALONE выглядит следующим образом:

TIMEID      | NAME
-----------------------------------
VALUE       | VALUE
VALUE       | VALUE
VALUE       | VALUE

Но если я выполню эту процедуру и передам ее dummydate (sysdate - 12 или дата вроде '16 .07.2010 10:32:50'), моя жаба выдаст мне сообщение "Процедура выполнена", моя таблица останется пустой...!Но, как уже было сказано, большой оператор Select дает результаты, поэтому не следует пытаться вставить пустой набор результатов ...!Может кто-нибудь сказать мне, почему моя процедура не работает?

Спасибо за каждый полезный ответ.=)

Привет!

PS:

Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
into pformateddate 
from dual;

требуется для сокращения значения pDate!Я проверил это, так что это тоже работает, и вы можете игнорировать это во всей логике.Это просто здесь, чтобы дать вам полную картину ситуации!

Ответы [ 3 ]

3 голосов
/ 28 июля 2010

Это очень распространенный шаблон на форумах по SQL. Шаблон ОП говорит

"Я запускаю этот SQL в своем листе TOAD (или что угодно) и это работает. Но когда Я включаю это в другом контексте - такой как хранимая процедура - это не работает Что дает? "

Что дает то, что два утверждения не совпадают . Где-то происходит неправильная транскрипция. Возможно, соединение было пропущено или добавлено дополнительное. Наиболее вероятным источником ошибок является замена литералов в рабочей таблице параметрами в хранимой процедуре.

Очевидно, я не могу сказать вам, в чем заключается разница. Все, что я могу сделать, - это убедить вас внимательно изучить два оператора SQL и выяснить расхождение.

Если вы действительно не можете найти никакой разницы, вам нужно будет отладить ваш код. Самый быстрый способ начать с отладчика дьявола. После оператора вставки добавьте эту строку:

dbms_output.put_line('Rows inserted = '||to_char(sql%rowcount));

Вам потребуется включить DBMS_OUTPUT в TOAD; где-то есть вкладка для этого. Это по крайней мере скажет вам, действительно ли запрос возвращает ноль строк или ваша процедура вставляет строки, и вы по какой-то причине их не видите. Это две разные проблемы.

0 голосов
/ 28 июля 2010

Не совсем относится к вашей проблеме, но это

Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
into pformateddate 
from dual;

- это просто длинный способ удаления элемента времени из переданного параметра. Это делает то же самое:

Select trunc(pdate) 
into pformateddate 
from dual; 

Или, как действительно указывает Тони, прямое задание:

pformateddate := trunc(pdate);
0 голосов
/ 28 июля 2010

Вам понадобится COMMIT в сеансе Toad, где вы выполняли эту процедуру, прежде чем вы сможете увидеть эти данные в таблице в любом другом сеансе, например в браузере таблиц. Вы помните, чтобы сделать это?

...