【问题标题】:Cursor parameters and aggregating results光标参数和聚合结果
【发布时间】:2015-08-05 14:04:22
【问题描述】:

我有以下游标声明:

CURSOR c_2800s(map_code VARCHAR2,serv_code VARCHAR2,sub_serv_code         VARCHAR2,bill_to_datetime VARCHAR2) IS
SELECT DISTINCT kndtctc.tctc_cncclipu,TCTC_CNCTAEJE,TCTC_CNNETNAM,nvl(TEXE_CNASUPRO,0000000000),nvl(TEXE_CNNETNAM,00) 
FROM KNDTSCM, KNDTCTC, KNDTEXE
WHERE trim(TSCM_CNMAPCO) = map_code
AND KNDTSCM.TSCM_CNCONTRA = kndtctc.tctc_cncclipu
AND KNDTCTC.TCTC_CNTIPCLI = 'C'  -- FOR H2H --
AND KNDTCTC.TCTC_CNESTADO IN ('01','03')
AND kndtctc.tctc_cncclipu = kndtexe.texe_cncclipu 
AND kndtexe.texe_cnestado in ('01','03')
AND KNDTSCM.TSCM_CNESTADO IN ('01','03')
AND trim(kndtscm.tscm_cnservic) = trim(kndtexe.texe_cnfuncid)
AND trim(kndtscm.tscm_cnsubser) = trim(kndtexe.texe_cnsubser)
AND trim(KNDTEXE.TEXE_CNFUNCID) = serv_code
AND  trim(kndtexe.texe_cnsubser) = sub_serv_code;

对于任何 serv_code,可以有多个 subserv_code(I1-I8) 和 map_code(1009、1010 等)。该程序使用该光标为客户添加文件传输量。它是一个现有的 SP,最初编写它时不必考虑上述的多种选择。我需要对它进行最低限度的更改,以考虑现在可用的多个选项。光标的打开如下(我添加了它不起作用,因为我只需要一个基于返回每个帐户的卷的查询的输出(texe_cnasupro):

IF(r_input_billing.r_bill_srvc_code=2806) THEN
OPENc_2800s_mnthy_mntce
('1224','3050','I2',r_input_billing.r_billing_to_datetime);
LOOP
FETCH c_2800s_mnthy_mntce INTO R_INFORPT_RECORD;
EXIT WHEN c_2800s_mnthy_mntce%NOTFOUND;
r_cnt:=r_cnt+1;
dbms_output.put_line('Master Account:'||R_INFORPT_RECORD.r_master_acct);
dbms_output.put_line('Account:'||R_INFORPT_RECORD.r_acct);
dbms_output.put_line('Bank ID:'||R_INFORPT_RECORD.r_bnk_id);
-- Write this line to the output file --
UTL_FILE.PUTF(output_file_handle,r_input_billing.r_bill_srvc_code||'|'||r_input_billing.r_billing_from_datetime||'|'||r_input_billing.r_billing_to_datetime||'|'||r_input_billing.r_frequency||'|'||to_char(R_INFORPT_RECORD.r_master_acct,'FM0000000000')||'|'||to_char(R_INFORPT_RECORD.r_master_bnk_id,'FM00')||'|'||to_char(R_INFORPT_RECORD.r_acct,'FM0000000000')||'|'||to_char(trim(R_INFORPT_RECORD.r_bnk_id),'FM00')||'|00000000000000001|'||systimestamp||'|\n' );                      
END LOOP;
CLOSE c_2800s_mnthy_mntce;

ELSIF(r_input_billing.r_bill_srvc_code=2806) THEN
OPEN c_2800s_mnthy_mntce
('1224','3050','I6',r_input_billing.r_billing_to_datetime); 
LOOP
FETCH c_2800s_mnthy_mntce INTO R_INFORPT_RECORD;
EXIT WHEN c_2800s_mnthy_mntce%NOTFOUND;
r_cnt:=r_cnt+1;
dbms_output.put_line('Master Account:'||R_INFORPT_RECORD.r_master_acct);
dbms_output.put_line('Account:'||R_INFORPT_RECORD.r_acct);
dbms_output.put_line('Bank ID:'||R_INFORPT_RECORD.r_bnk_id);
-- Write this line to the output file --
UTL_FILE.PUTF(output_file_handle,r_input_billing.r_bill_srvc_code||'|'||r_input_billing.r_billing_from_datetime||'|'||r_input_billing.r_billing_to_datetime||'|'||r_input_billing.r_frequency||'|'||to_char(R_INFORPT_RECORD.r_master_acct,'FM0000000000')||'|'||to_char(R_INFORPT_RECORD.r_master_bnk_id,'FM00')||'|'||to_char(R_INFORPT_RECORD.r_acct,'FM0000000000')||'|'||to_char(trim(R_INFORPT_RECORD.r_bnk_id),'FM00')||'|00000000000000001|'||systimestamp||'|\n' );                      
END LOOP;
CLOSE c_2800s_mnthy_mntce;

我需要帮助聚合游标的结果以实现所需的结果(不会弄乱已经存在的内容,上面的游标用于今天已经在使用的大量其他 serv_codes/map_codes)我在上面提到过。感谢您的宝贵时间!

【问题讨论】:

    标签: sql oracle plsql cursor


    【解决方案1】:

    您可以尝试制作 subserv_code 和 map_code 值表,并将它们作为表连接到光标中,而不是将它们作为参数传递给光标:

    -- Use an appropropriate data type for SUB_SERV_CODE
    CREATE OR REPLACE TYPE SUB_SERV_CODE_T AS OBJECT (SUB_SERV_CODE VARCHAR2(30));
    /
    CREATE OR REPLACE TYPE SUB_SERV_CODE_TT AS TABLE OF SUB_SERV_CODE_T;
    /
    
    -- Use an appropropriate data type for MAP_CODE
    CREATE OR REPLACE TYPE MAP_CODE_T AS OBJECT (MAP_CODE VARCHAR2(30));
    /
    CREATE OR REPLACE TYPE MAP_CODE_TT AS TABLE OF MAP_CODE_T;
    /
    
    
    DECLARE
      -- Table variables passed in the cursor parameters can't
      -- be used in the from clause.  Intead they must be
      -- declared and in scope before the cursor is declared.
      sub_serv_code SUB_SERV_CODE_TT;
      map_code MAP_CODE_TT;
    
      CURSOR c_2800s( serv_code VARCHAR2
                    , bill_to_datetime VARCHAR2 )
      IS
       SELECT DISTINCT kndtctc.tctc_cncclipu
            , TCTC_CNCTAEJE
            , TCTC_CNNETNAM
            , NVL( TEXE_CNASUPRO, 0000000000 )
            , NVL( TEXE_CNNETNAM, 00 )
         FROM KNDTSCM
         JOIN KNDTCTC
           ON KNDTCTC.TCTC_CNCCLIPU = KNDTSCM.TSCM_CNCONTRA
         JOIN KNDTEXE
           ON KNDTEXE.TEXE_CNCCLIPU = KNDTCTC.TCTC_CNCCLIPU
         JOIN TABLE(map_code)
           ON TRIM( TSCM_CNMAPCO ) = map_code.map_code
         JOIN TABLE(sub_serv_code)
           ON trim( kndtexe.texe_cnsubser ) = sub_serv_code.sub_serv_code
        WHERE KNDTCTC.TCTC_CNTIPCLI         = 'C' -- FOR H2H --
          AND KNDTCTC.TCTC_CNESTADO        IN( '01', '03' )
          AND kndtexe.texe_cnestado        IN( '01', '03' )
          AND KNDTSCM.TSCM_CNESTADO        IN( '01', '03' )
          AND trim( kndtscm.tscm_cnservic ) = trim( kndtexe.texe_cnfuncid )
          AND trim( kndtscm.tscm_cnsubser ) = trim( kndtexe.texe_cnsubser )
          AND trim( KNDTEXE.TEXE_CNFUNCID ) = serv_code;
    
      R_INFORPT_RECORD  c_2800s%ROWTYPE;
    BEGIN
      -- One method to initialize a table variable
      sub_serv_code := SUB_SERV_CODE_TT();
      sub_serv_code.extend(8);
      sub_serv_code(1) := sub_serv_code_t('I1');
      sub_serv_code(2) := sub_serv_code_t('I2');
      sub_serv_code(3) := sub_serv_code_t('I3');
      sub_serv_code(4) := sub_serv_code_t('I4');
      sub_serv_code(5) := sub_serv_code_t('I5');
      sub_serv_code(6) := sub_serv_code_t('I6');
      sub_serv_code(7) := sub_serv_code_t('I7');
      sub_serv_code(8) := sub_serv_code_t('I8');
    
      -- Another method to initialze a table variable
      with t1(map_code) as (
        select '1009' from dual union all
        select '1010' from dual
      ) select MAP_CODE_T(map_code)
          bulk collect into map_code
          from t1;
    
      -- You'll need to fix the open cursor call
      OPEN c_2800s('3050','r_input_billing.r_billing_datetime');
      LOOP
        FETCH c_2800s into R_INFORPT_RECORD;
        exit when c_2800s%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(R_INFORPT_RECORD.sub_serv_code);
      END LOOP;
      CLOSE c_2800s;
    END;
    /
    

    无法访问您的表格,这是我用于测试的示例光标,以代替上面显示的光标:

      CURSOR c_2800s( serv_code VARCHAR2
                    , bill_to_datetime VARCHAR2 )
      IS
       SELECT SUB_SERV_CODE FROM TABLE(sub_serv_code);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2016-07-21
      • 2018-10-17
      • 2018-06-18
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多