2016-11-17 68 views
-1

我的临时表是 -如何将动态光标传递到临时表中?

begin 
    stmt := Create local temporary TABLE 

      FMO_APP.DYNAMICSQL(ENGINE_FAMILY_CODE VARCHAR2(30 BYTE), 
           CONTRACT_NAME VARCHAR2(200 BYTE) NOT NULL 
           ENABLE, 
           CONTRACT_SEQ_ID NUMBER(9, 0) NOT NULL 
           ENABLE, 
           USAGE_MONTH VARCHAR2(10 BYTE), 
           INVOICE_NUM VARCHAR2(14 BYTE) NOT NULL, 

           INVOICE_AMT NUMBER(15, 2), 
           INVOICE_BILLING_DATE DATE, 
           CREATED_DATE DATE, 
           BILLING_INVOICE_TYPE VARCHAR2(255 BYTE), 
           EFH NUMBER(11, 3), 
           EC NUMBER(9, 0), 
           CANCELLED_INVOICE_NUM VARCHAR2(14 BYTE), 
           RESTORED_ESN VARCHAR2(12 BYTE), 
           PAYMENT_TERM_TEXT VARCHAR2(60 BYTE), 
           RECON_INVOICE_NUM VARCHAR2(1 BYTE), 
           RECON_PERIOD VARCHAR2(1 BYTE), 
           PAYMENT_DUE_DATE DATE, 
           CONTRACT_CODE VARCHAR2(4 BYTE) NOT NULL 
           ENABLE, 
           PRODUCT_LINE_CODE VARCHAR2(20 BYTE) NOT NULL ENABLE, 
           PAYMENT_STATUS VARCHAR2(50 BYTE), 
           RN NUMBER, 
           COUNT NUMBER) on Commit Delete Rows; 

    execute immediate stmt; 

    insert into FMO_APP.DYNAMICSQL (cur_result); --is this correct ? 

    end; 

动态游标是 -

open cur for v_sql; 
LOOP 
    FETCH cur 
    INTO cur_result; 
    EXIT WHEN cur%NOTFOUND; 

--v_sql is a dynamic query. 
--cur is ref_cur. 
--cur_result  dynamicsql%ROWTYPE; 

我需要从游标使用临时表来存储值,并用它后来更新表。

以下是完整的代码。

BEGIN 


usage_month_parameters := usage_month_array(); 

open cur for v_sql; 
LOOP 
    FETCH cur 
    INTO cur_result; 
    EXIT WHEN cur%NOTFOUND; 

    begin 
    stmt := Create local temporary TABLE 

      FMO_APP.DYNAMICSQL(ENGINE_FAMILY_CODE VARCHAR2(30 BYTE), 
           CONTRACT_NAME VARCHAR2(200 BYTE) NOT NULL 
           ENABLE, 
           CONTRACT_SEQ_ID NUMBER(9, 0) NOT NULL 
           ENABLE, 
           USAGE_MONTH VARCHAR2(10 BYTE), 
           INVOICE_NUM VARCHAR2(14 BYTE) NOT NULL, 

           INVOICE_AMT NUMBER(15, 2), 
           INVOICE_BILLING_DATE DATE, 
           CREATED_DATE DATE, 
           BILLING_INVOICE_TYPE VARCHAR2(255 BYTE), 
           EFH NUMBER(11, 3), 
           EC NUMBER(9, 0), 
           CANCELLED_INVOICE_NUM VARCHAR2(14 BYTE), 
           RESTORED_ESN VARCHAR2(12 BYTE), 
           PAYMENT_TERM_TEXT VARCHAR2(60 BYTE), 
           RECON_INVOICE_NUM VARCHAR2(1 BYTE), 
           RECON_PERIOD VARCHAR2(1 BYTE), 
           PAYMENT_DUE_DATE DATE, 
           CONTRACT_CODE VARCHAR2(4 BYTE) NOT NULL 
           ENABLE, 
           PRODUCT_LINE_CODE VARCHAR2(20 BYTE) NOT NULL ENABLE, 
           PAYMENT_STATUS VARCHAR2(50 BYTE), 
           RN NUMBER, 
           COUNT NUMBER) on Commit Delete Rows; 

    execute immediate stmt; 

    insert into FMO_APP.DYNAMICSQL (cur_result); 

    end; 

    begin 
    select fi.billing_invoice_type, mi.tag_type 
     into v_inv_type, v_tag_type 
     from fmo_op2_invoice fi, fmo_op2_manual_invoice_items mi 
    where fi.invoice_num = mi.invoice_num; 

    if upper(v_inv_type) = 'M' and upper(v_tag_type) = 'P' then 

     select count(distinct mi.item_date) 
     into item_date_count 
     from fmo_op2_manual_invoice_items mi 
     where mi.invoice_num = cur_result.INVOICE_NUM; 

     if item_date_count = 1 then 
     select distinct mi.item_date 
      into v_item_date 
      from fmo_op2_manual_invoice_items mi 
     where mi.invoice_num = cur_result.invoice_num; 

     SELECT to_char(v_item_date, 'yyyy - MM - dd') 
      into var_usage_month 
      from dual; 

     elsif item_date_count > 1 then 
     var_usage_month := to_char('MULTIPLE'); 

     else 
     var_usage_month := to_char(cur_result.USAGE_MONTH, 
            'yyyy - MM - dd'); 
     end if; 

     BEGIN 
     v_usage_month_arr.EXTEND; 

     v_usage_month_arr(var_num) := usage_month_value_obj(cur_result.ENGINE_FAMILY_CODE, 

                  cur_result.CONTRACT_NAME, 
                  cur_result.CONTRACT_SEQ_ID, 
                  var_usage_month, 
                  cur_result.INVOICE_NUM, 
                  cur_result.INVOICE_AMT, 
                  cur_result.INVOICE_BILLING_DATE, 
                  cur_result.CREATED_DATE, 
                  cur_result.BILLING_INVOICE_TYPE, 
                  cur_result.EFH, 
                  cur_result.EC, 
                  cur_result.CANCELLED_INVOICE_NUM, 
                  cur_result.RESTORED_ESN, 
                  cur_result.PAYMENT_TERM_TEXT, 
                  cur_result.RECON_INVOICE_NUM, 
                  cur_result.RECON_PERIOD, 
                  cur_result.PAYMENT_DUE_DATE, 
                  cur_result.CONTRACT_CODE, 
                  cur_result.PRODUCT_LINE_CODE, 
                  cur_result.PAYMENT_STATUS 

                  ); 
     end; 

    else 
     var_usage_month := to_char(cur_result.USAGE_MONTH, 
           'yyyy - MM - dd'); 

    end if; 
    end; 

end loop; 
close cur; 

OPEN p_out_contract_data FOR 
    select cast(v_usage_month_arr as fmo_op2_manual_table_type) 
    from dual; 

commit; 
+1

你为什么试图在代码中创建表?除了您的语法不正确以及缺少将您的create table语句转换为字符串的单引号(因此您可以将它存储在stmt变量中)之外,它看起来像表具有固定的结构。 我会做的是在数据库中创建表作为GTT(全局临时表 - 表是永久对象,但数据仅存储在会话级别),然后在代码中引用它。但是,您的代码并不实际引用您的临时表;所以为什么要打扰呢? – Boneist

回答

1

您对Oracle临时表的理解是完全错误的。您需要创建它只有一次,任何存储的代码外(过程,函数,包):

create temporary table my_temporary_table (...) on commit delete rows; 

之后,你就可以在任何地方使用它,你需要的。与数据使用insert ... select语句填充:

procedure my_proc (...) is 
    ... 
begin 
    insert into my_temporary_table (...) 
    select ... 
    from source_table; 

end; 

表将在提交之后被清除。