【问题标题】:Subprogram or cursor '' reference is out of scope子程序或游标''引用超出范围
【发布时间】:2022-01-24 07:29:22
【问题描述】:

告诉我在处理当前表时如何引用该列。我需要对已经计算过的字段进行计算,通过化名引用表字段没有帮助,也许我错过了其他东西,但如果有人向我指出我的愚蠢,我会很高兴。我在一个简单的地方看不到解决方案:(

非常感谢!

问题出在这个地方PLS-00225:子程序或游标'F'引用超出范围:

then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub

身体 pck:

create or replace package body dma.fill_f101_round_f is
  procedure Log
  ( i_message                      in varchar2
  ) 
  is
  begin
    dma.logger.writeLog('[' || c_MartName || '] ' || i_message);
  end;
  ----------------------------------------------------------------------------------------------------

  ----------------------------------------------------------------------------------------------------
  procedure fill
  ( i_OnDate                       in date
  )
  is
  begin

    Log( '[BEGIN] fill(i_OnDate => date ''' 
         || to_char(i_OnDate, 'yyyy-mm-dd') 
         || ''');'
       );
    
    Log( 'delete on_date = ' 
         || to_char(i_OnDate, 'yyyy-mm-dd')
       );

    delete
      from dma.DM_F101_ROUND_F f
     where trunc(i_OnDate, 'mm')  =  from_date
       and last_day(i_OnDate)    =  to_date;
   
    Log('insert');
   
    insert 
      into dma.dm_f101_round_f f
           ( from_date         
           , to_date           
           , chapter           
           , ledger_account    
           , characteristic    
           , balance_in_rub    
           , balance_in_val    
           , balance_in_total  
           , turn_deb_rub      
           , turn_deb_val      
           , turn_deb_total    
           , turn_cre_rub      
           , turn_cre_val      
           , turn_cre_total    
           , balance_out_rub  
           , balance_out_val   
           , balance_out_total 
           )
    select trunc(i_OnDate, 'mm')                 as from_date,
           last_day(i_OnDate)                    as to_date,
           s.chapter                             as chapter,
           substr(acc_d.account_number, 1, 5)    as ledger_account,
           acc_d.char_type                       as characteristic,
           -- RUB balance
           sum( case 
                  when cur.currency_code in ('643', '810')
                  then b.balance_out
                  else 0
                 end
              )                                  as balance_in_rub,
          -- VAL balance converted to rub
          sum( case 
                 when cur.currency_code not in ('643', '810')
                 then b.balance_out * exch_r.reduced_cource
                 else 0
                end
             )                                   as balance_in_val,
          -- Total: RUB balance + VAL converted to rub
          sum(  case 
                 when cur.currency_code in ('643', '810')
                 then b.balance_out
                 else b.balance_out * exch_r.reduced_cource
               end
             )                                   as balance_in_total  ,
           -- RUB debet turnover
           sum(case 
                 when cur.currency_code in ('643', '810')
                 then at.debet_amount_rub
                 else 0
               end
           )                                     as turn_deb_rub,
           -- VAL debet turnover converted
           sum(case 
                 when cur.currency_code not in ('643', '810')
                 then at.debet_amount_rub
                 else 0
               end
           )                                     as turn_deb_val,
           -- SUM = RUB debet turnover + VAL debet turnover converted
           sum(at.debet_amount_rub)              as turn_deb_total,
           -- RUB credit turnover
           sum(case 
                 when cur.currency_code in ('643', '810')
                 then at.credit_amount_rub
                 else 0
               end
              )                                  as turn_cre_rub,
           -- VAL credit turnover converted
           sum(case 
                 when cur.currency_code not in ('643', '810')
                 then at.credit_amount_rub
                 else 0
               end
              )                                  as turn_cre_val,
           -- SUM = RUB credit turnover + VAL credit turnover converted
           sum(at.credit_amount_rub)             as turn_cre_total,
           
           sum( case 
                 when cur.currency_code     in ('643','810') and acc_d.char_type = 'A'
                 then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
                 
                 when cur.currency_code     in ('643','810') and acc_d.char_type = 'P'
                 then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
                 else 0
                end
             )                                                          as balance_out_rub,
          sum(  case 
                 when cur.currency_code not in ('643', '810') and acc_d.char_type = 'A'
                 then f.balance_in_val - f.turn_cre_val + f.turn_deb_val
                 
                 when cur.currency_code not in ('643', '810') and acc_d.char_type = 'P'
                 then f.balance_in_val + f.turn_cre_val - f.turn_deb_val
                 else 0
               end
             )                                                          as balance_out_val,
           sum (f.balance_out_val  + f.balance_out_rub)                 as balance_out_total 
      from ds.md_ledger_account_s s
      join ds.md_account_d acc_d
        on substr(acc_d.account_number, 1, 5) = s.ledger_account
      join ds.md_currency_d cur
        on cur.currency_rk = acc_d.currency_rk
      left 
      join ds.ft_balance_f b
        on b.account_rk = acc_d.account_rk
       and b.on_date  = trunc(i_OnDate, 'mm') - 1
      left 
      join ds.md_exchange_rate_d exch_r
        on exch_r.currency_rk = acc_d.currency_rk
       and i_OnDate between exch_r.data_actual_date and exch_r.data_actual_end_date
      left 
      join dma.dm_account_turnover_f at
        on at.account_rk = acc_d.account_rk
       and at.on_date between trunc(i_OnDate, 'mm') and last_day(i_Ondate)
     where i_OnDate between s.start_date and s.end_date
       and i_OnDate between acc_d.data_actual_date and acc_d.data_actual_end_date
       and i_OnDate between cur.data_actual_date and cur.data_actual_end_date
     group by s.chapter,
           substr(acc_d.account_number, 1, 5),
           acc_d.char_type;

    Log('[END] inserted ' || to_char(sql%rowcount) || ' rows.');

    commit;
    
  end;
  ----------------------------------------------------------------------------------------------------

end fill_f101_round_f;
/ ```

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    这是f

    into dma.dm_f101_round_f f 
                             ^
                          here it is
    

    f.balance_in_rub是这样的:

           -- RUB balance
           sum( case 
                  when cur.currency_code in ('643', '810')
                  then b.balance_out
                  else 0
                 end
              )                                  as balance_in_rub,
                                                    --------------
                                                    here it is
    

    您不能简单地通过命名来引用正在插入的列;在这种情况下它是未知。如果要执行一些计算,则必须使用“源”本身来执行此操作,即

    then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
    

    会变成

    then
           sum(case 
                  when cur.currency_code in ('643', '810')
                  then b.balance_out
                  else 0
                 end
              ) -
           sum(case 
                 when cur.currency_code in ('643', '810')
                 then at.credit_amount_rub
                 else 0
               end
              ) +
           sum(case 
                 when cur.currency_code in ('643', '810')
                 then at.debet_amount_rub
                 else 0
               end
           )
    

    即你会重复使用所有这些代码。恐怕不太漂亮。

    另一种选择是先执行insert,然后执行update,然后就可以了

    update dm_f101_round_f f set
      f.balance_out_rub = f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
    where ...
    

    【讨论】:

    • 感谢您的回答。然后不要告诉我在这种情况下如何进行求和操作。 sum (f.balance_out_val + f.balance_out_rub) as balance_out_total
    • 不客气。如果您的意思是说我是否可以建议如何计算 BALANCE_OUT_TOTAL,那么它将 - 再次 - 更新。在那里,你会替换例如BALANCE_OUT_RUB 及其所有列:BALANCE_IN_RUB + TURN_CRE_RUB + TURN_DEB_RUB。或者分两步更新;首先计算单独的列,然后计算摘要。
    • 非常感谢您的帮助。祝你有美好的一天,新年快乐!
    • 没问题;新年快乐!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    相关资源
    最近更新 更多