【问题标题】:need to get the output of 2 cursors in one temp table需要在一个临时表中获得 2 个游标的输出
【发布时间】:2012-09-04 00:01:41
【问题描述】:

这是我的第一个程序(示例)

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 插入,但在我的情况下,重复的行被插入。任何帮助,将不胜感激。如果有人需要更多信息,请发布。

【问题讨论】:

  • 不,您的实际问题是您正在使用其他两个表中的值填充一个表,而没有+定义它们之间的关系+。目前,您的第一次运行可能会在 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)。坦率地说,这是荒谬的。
  • 如果给定了需求 A,您应该交付 A,但不证明 A = Z 并交付 Z,只要将数据插入到临时表中,迭代就可以是没有问题的任何顺序。有道理吗?
  • 不,这没有意义。您想用两个现有表(t1t2)中的列填充一个新表(t_new)。我希望有一些业务逻辑定义t1t2 之间的连接。但你什么都没有。所以基本上你正在用通过将t1 中的随机行焊接到t2 中的随机行而产生的记录填充t_new。编程是一种逻辑练习,工作描述的一部分是挑战不完整、模棱两可或完全错误的“要求”。
  • 出于好奇,如果我问这两个表之间是否存在关系(以 r_date 作为公共列)。您能否阐明该方法但不要修改第一个过程,因为它仍然必须返回给定的两个参考游标。

标签: sql plsql cursor oracle11g procedure


【解决方案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 个 refcursors,那么我的方法不相关...
不过,您可以做的是有 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来提高性能,见例子here

【讨论】:

  • 意思是 union 我应该将它们传达为 JOIN ,但是如果数据很多(您的观点!!!),拥有 FULL OUTER JOIN 可能会影响性能。关于临时表,我需要它,因为这是要求设置为:他们会给我 2 个 refcursor 作为输入,我应该给他们 1 个 temptable,其中包含从 refcursor 获取的所有数据。如果它可以解释我如何修改/实现这个“插入选择”到我上面解释的解决方案方法,那就太好了。
  • 您以正确的方式跟踪我“BULK INSERT/COLLECT”是我事后的想法,但如何使用 BULK 机制插入单个表,该机制将读取两个参考光标。我知道我要求用勺子喂食,但如果我能得到至少一两个链接,那就太好了。
  • 好的,我可以有 2 个插入语句,但我想这样做会在临时表中插入 4+5=9 行(对于上面的 ex),但我认为是在临时表中有 5 行(即 - 两个游标的最大值 = 在临时表中插入的行数)。如果没有其他办法,那么我想我必须通过两次插入。请提出建议。
猜你喜欢
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2012-08-08
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多