如何将动态光标传递到临时表?

时间:2016-11-17 15:11:31

标签: sql oracle plsql

我的临时表是 -

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 个答案:

答案 0 :(得分: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;

提交后将清除表。