нужно получить вывод 2 курсоров в одной временной таблице

Вот моя первая процедура (пример)

CREATE OR REPLACE PROCEDURE GPTOWNER_CORP_AMF.testt1
AS
po_status VARCHAR2(100);
po_cur_1 SYS_REFCURSOR;
po_cur_2 SYS_REFCURSOR;
BEGIN
OPEN po_cur_1 FOR
select app_var_row_seq,app_var_name,app_var_value,app_var_description,r_date
 from TMP_PMT_APP_VARIABLES_REF
where ROWNUM < 5;

OPEN po_cur_2 FOR
select config_to_lob_row_seq,config_row_seq,lobref_row_seq,r_date
 from  TMP_PMT_CONFIG_TO_LOB_DAT 
 where ROWNUM < 6;
 TESTT2(po_cur_1,po_cur_2,po_status);
 DBMS_output.put_line(po_status);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM||SQLCODE);
END;

Вот моя вторая процедура (пример)

CREATE OR REPLACE procedure GPTOWNER_CORP_AMF.testt2 (pi_cur_1 IN sys_refcursor, pi_cur_2 IN sys_refcursor,po_status OUT VARCHAR2)
AS
app_var_row_seq NUMBER;
app_var_name VARCHAR2(100);
app_var_value VARCHAR2(1000);
app_var_description VARCHAR2(1000);
r_date1 DATE;
config_to_lob_row_seq NUMBER;
config_row_seq VARCHAR2(100);
lobref_row_seq NUMBER;
r_date2 DATE;
BEGIN
    LOOP
        FETCH pi_cur_1 into app_var_row_seq,app_var_name,app_var_value,app_var_description,r_date1;
        FETCH pi_cur_2 into config_to_lob_row_seq,config_row_seq,lobref_row_seq,r_date2;

        EXIT WHEN (pi_cur_2%NOTFOUND AND pi_cur_1%NOTFOUND ) ; 

        INSERT INTO testt1testt2 (colid,col1,col2,col3,col4,col5,col6,col7,col8,col9) 
                    VALUES(colid.nextval,app_var_row_seq,app_var_name,app_var_value,app_var_description,r_date1,config_to_lob_row_seq,config_row_seq,lobref_row_seq,r_date2);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE ('rows inserted:' || pi_cur_1%ROWCOUNT || 'and' || pi_cur_2%ROWCOUNT);   
EXCEPTION
    WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE(SQLERRM||SQLCODE);
END;

Моя проблема заключается в том, что из первой процедуры я получаю два refcursor в качестве вывода, а во второй процедуре я пытаюсь прочитать их и поместить во временную таблицу, которая будет использоваться другой процедурой. Невозможно объединить два оператора select, поскольку они имеют разный набор выходных данных. Есть ли какой-либо лучший механизм для этого, так как в моем подходе я сталкиваюсь с проблемой, когда я запускаю первую процедуру (скажем, первый выбор возвращает 4 строки, а второй выбор возвращает 6 строк), необходимо, чтобы 6 строк были вставлены в временную таблицу но столбцы, которые считываются из первого выбора, будут вставлены как NULL, когда теперь будет выбрана строка, но в моем случае вставляется повторяющаяся строка. Любая помощь будет оценена по достоинству. И сделайте сообщение, если кому-то нужна дополнительная информация о том же.


person Abhishek    schedule 11.09.2012    source источник
comment
Нет, ваша реальная проблема заключается в том, что вы заполняете таблицу значениями из двух других таблиц без +определения отношения между ними+. На данный момент ваш первый запуск может создать записи в testt1testt2, составленные из (TMP_PMT_APP_VARIABLES_REF #1, TMP_PMT_CONFIG_TO_LOB_DAT #2) и (TMP_PMT_APP_VARIABLES_REF #2, TMP_PMT_CONFIG_TO_LOB_DAT #1). Тогда следующий запуск будет иметь (TMP_PMT_APP_VARIABLES_REF #2, TMP_PMT_CONFIG_TO_LOB_DAT #2) и (TMP_PMT_APP_VARIABLES_REF #1, TMP_PMT_CONFIG_TO_LOB_DAT #1). Что откровенно нелогично.   -  person APC    schedule 11.09.2012
comment
если вам было дано требование A, вы должны выполнить A , но не доказывать A = Z и доставлять Z, итерации могут быть любого порядка, который не является проблемой, пока данные вставляются во временную таблицу. Имеет смысл ?   -  person Abhishek    schedule 11.09.2012
comment
Нет, это не имеет смысла. Вы хотите заполнить новую таблицу (t_new) столбцами из двух существующих таблиц (t1, t2). Я ожидаю, что будет какая-то бизнес-логика, определяющая соединение между t1 и t2. Но у тебя их нет. Таким образом, вы заполняете t_new записями, полученными путем объединения случайных строк из t1 со случайными строками в t2. Программирование — это упражнение в логике, и часть описания работы — сложные требования, которые являются неполными, двусмысленными или просто неправильными.   -  person APC    schedule 12.09.2012
comment
Из моего любопытства, если я спрошу, есть ли связь между двумя таблицами (возьмите r_date в качестве общего столбца). Можете ли вы пролить свет на подход, но не изменяйте первую процедуру, поскольку она все еще должна возвращать два курсора ref, как указано.   -  person Abhishek    schedule 12.09.2012


Ответы (1)


Если я вас правильно понимаю, вам не нужно их объединять, но присоединяйте их.
Поскольку на самом деле между двумя таблицами нет никакой связи, и вы хотите, чтобы нули были в «обе стороны», вам нужно full outer join их.

Я не буду спрашивать вас, почему вы хотите, чтобы они оба находились в одной временной таблице, если между ними нет никакой связи. Но если вы сделаете это, почему бы просто не использовать insert-select ?

INSERT INTO testt1testt2 (colid,col1,col2,col3,col4,col5,col6,col7,col8,col9) 
SELECT colid.nextval, app_var_row_seq,app_var_name,app_var_value,app_var_description, t1.r_date,
                      config_to_lob_row_seq,config_row_seq,lobref_row_seq, t2.r_date
FROM (select app_var_row_seq,app_var_name,app_var_value,app_var_description,r_date
      from TMP_PMT_APP_VARIABLES_REF
      where ROWNUM < 5) t1 
FULL OUTER JOIN (select config_to_lob_row_seq,config_row_seq,lobref_row_seq,r_date
                 from  TMP_PMT_CONFIG_TO_LOB_DAT 
                 where ROWNUM < 6) t2 on 1=2

ОБНОВЛЕНИЕ:
Если требуется получить 2 рефкурсора, то мой подход не актуален...
Однако вы можете сделать 2 команды вставки, например:

INSERT INTO testt1testt2 (colid,col1,col2,col3,col4,col5,col6,col7,col8,col9) 
     VALUES (colid.nextval,app_var_row_seq,app_var_name,app_var_value,app_var_descript‌​ion,r_date1,null,null,null,null); 

а другой вроде:

INSERT INTO testt1testt2 (colid,col1,col2,col3,col4,col5,col6,col7,col8,col9)
     VALUES (colid.nextval,null,null,null,null,null,config_to_lob_row_seq,config_row_s‌​eq,lobref_row_seq,r_date2);

Если вы действительно хотите сделать это красиво, вы можете использовать bulk insert для повышения производительности, см. пример здесь

person A.B.Cade    schedule 11.09.2012
comment
Под объединением я должен был передать их как JOIN , но наличие FULL OUTER JOIN может повлиять на производительность, если данных много (ваши точки на нем !!!) . Что касается временной таблицы, она мне нужна, потому что это требование установлено следующим образом: они дадут мне 2 refcursor в качестве входных данных, и я должен дать им 1 temptable, содержащий все данные, извлеченные из refcursor. И было бы очень хорошо, если бы можно было объяснить, как я могу изменить/внедрить этот выбор вставки в мой вышеописанный подход к решению. - person Abhishek; 11.09.2012
comment
Вы отследили меня на правильном пути. BULK INSERT/COLLECT - это то, о чем я тоже думал задним числом, но как вставить в одну таблицу, используя механизм BULK, который будет читать два курсора ссылки. Я знаю, что прошу кормление с ложки, но было бы очень хорошо, если бы я мог получить хотя бы одну или две ссылки. - person Abhishek; 11.09.2012
comment
Хорошо, понял, у меня может быть 2 оператора вставки, но я думаю, что при этом он вставит 4 + 5 = 9 строк во временную таблицу (для приведенного выше примера), но я думал, что во временной таблице будет 5 строк ( т.е. - максимальное количество двух курсоров = количество строк, вставляемых во временную таблицу). Если нет другого пути, то, думаю, мне придется использовать две вставки. Пожалуйста, предложите. - person Abhishek; 11.09.2012