FOR LOOP 脚本未运行

Posted

技术标签:

【中文标题】FOR LOOP 脚本未运行【英文标题】:FOR LOOP script not running 【发布时间】:2014-06-04 09:50:33 【问题描述】:

我正在尝试在 Oracle 中执行一个查询,其中输入将是一个日期范围,然后查询将在两个日期之间有多少天执行,输入日期也用作参数查询。即,如果我输入的日期范围是 5 月 28 日 - 31 日,则查询将执行四次(5 月 28 日、29 日、30 日、31 日),然后返回该日期范围内每个日期的结果集,然后合并将所有结果集合并为一个大结果集。我正在尝试使用FOR LOOP 来做到这一点。到目前为止,我有这个:

DECLARE

Bus_Date_1 date := '28-MAY-2013';
Bus_Date_2 date := '31-MAY-2013';
Date_Iter date;
Date_Diff integer;

BEGIN

Date_Diff := (Bus_Date_2 - Bus_Date_1) + 1;    

Date_Iter := Bus_Date_1;

FOR SL_Ctr in 1 .. Date_Diff
LOOP
select *
    from (
        select
            cdav.bank_id,
            ent.bank_desc Bank_Description,
            cdav.sol_id,
            sol.sol_desc SOL_Description,
            cdav.gl_sub_head_code GLSH_Code,
            decode(cdav.gl_sub_head_code,
                '10301',1,
                '10403',2, '60403',2, '10501',2, '60501',2, '10502',2, 
                '10503',2, '10504',2, '10505',2, '10507',2, '10509',2, 
                '60509',2, '10511',2, '10518',2, '60518',2, '10523',2, 
                '60523',2, '10551',2, '10552',2, '10553',2, '10554',2, 
                '10555',2, '10557',2, '10559',2, '10561',2, '10568',2, 
                '10573',2,
                '12336',3, '62336',3, '10401',3, '60402',3, 4 ) GLSH_SET ,
            gsh.gl_sub_head_desc GLSH_Name,
            case
                when (cast(substr(cdav.gl_sub_head_code,0,1) as int) >= 1
                    and cast(substr(cdav.gl_sub_head_code,0,1) as int) <= 5)
                then 'R'
                when cast(substr(cdav.gl_sub_head_code,0,1) as int) = 0
                    or (cast(substr(cdav.gl_sub_head_code,0,1) as int) >= 6
                    and cast(substr(cdav.gl_sub_head_code,0,1) as int) <= 9)
                then 'F'
            end book_type,
            gam.foracid account_number,
            gam.acct_name,
            cdav.tran_crncy_code Tran_Currency,
            cdav.value_date,
            cdav.tran_date Transaction_Date,
            cdav.gl_date,
            cdav.tran_particular,
            rank() over(partition by gam.foracid order by eab.eod_date desc) eod_date_rank,
            eab.eod_date,
            case when
                (select tran_date_bal from tbaadm.eab
                    where eab.eod_date = (select max(eab.eod_date) from tbaadm.eab
                        where cdav.acid = eab.acid and eab.eod_date < '28-MAY-2013') -- current date in the LOOP should be here
                    and cdav.acid = eab.acid
                    and cdav.bank_id = eab.bank_id) is not null
                then (select tran_date_bal from tbaadm.eab
                    where eab.eod_date = (select max(eab.eod_date) from tbaadm.eab
                        where cdav.acid = eab.acid and eab.eod_date < '28-MAY-2013') -- current date in the LOOP should be her
                    and cdav.acid = eab.acid
                    and cdav.bank_id = eab.bank_id)
                else 0
            end beg_tran_date_bal,
            (select tran_date_bal from tbaadm.eab eab
                where eod_date = (select max(eab.eod_date) from tbaadm.eab eab
                    where cdav.acid = eab.acid and eab.eod_date <= '28-MAY-2013') -- current date in the LOOP should be her
                and cdav.acid = eab.acid
                and cdav.bank_id = eab.bank_id) end_tran_date_bal,
            ott.ref_num OAP_Ref_No,
            trim(cdav.tran_id) Transaction_ID,
            --cdav.dth_init_sol_id Initiating_SOL_ID,
            'PCC_Code',
            cdav.tran_rmks Tran_Remarks,
            case
                when (cdav.part_tran_type = 'D')
                then (cdav.tran_amt)
            end dr_amount,
            case
                when (cdav.part_tran_type = 'C')
                then (cdav.tran_amt)
            end cr_amount

        from tbaadm.ctd_dtd_acli_view cdav
            left outer join tbaadm.gam
                on cdav.bank_id = gam.bank_id and cdav.acid = gam.acid
            left outer join tbaadm.gsh
                on gam.bank_id = gsh.bank_id and gam.sol_id = gsh.sol_id
                and gam.gl_sub_head_code = gsh.gl_sub_head_code
                and gam.acct_crncy_code = gsh.crncy_code
            left outer join tbaadm.sol
                on cdav.bank_id = sol.bank_id and cdav.sol_id = sol.sol_id
            left outer join tbaadm.eab
                on gam.bank_id = eab.bank_id and gam.acid = eab.acid
            left outer join tbaadm.cnc
                on gam.bank_id = cnc.bank_id and gam.acct_crncy_code = cnc.crncy_code
            left outer join crmuser.end ent
                on cdav.bank_id = ent.bank_id
            left outer join tbaadm.gct
                on cdav.bank_id = gct.bank_id
            left outer join tbaadm.ott
                on cdav.tran_id = ott.tran_id and cdav.tran_date = ott.tran_date
                and cdav.part_tran_srl_num = ott.part_tran_srl_num
                and cdav.bank_id = ott.bank_id and cdav.acid = ott.acid

        where
            gam.acct_ownership = 'O'
            and cdav.bank_id = 'CBC01'
            and cdav.gl_date = '28-MAY-2013' -- current date in the LOOP should be her
            and (gam.gl_sub_head_code in ('10301','10403','60403',
                '10501','60501','10502','10503','10504','10505',
                '10507','10509','60509','10511','10518','60518',
                '10523','60523','10551','10552','10553','10554',
                '10555','10557','10559','10561','10568','10573',
                '12336','62336','10401','60402')
                or gam.acct_classification_flg in ('I','E')
                )
            and trim(cdav.del_flg) in ('N', null)
            and trim(gam.del_flg) in ('N', null)
            and trim(gsh.del_flg) in ('N', null)
            and trim(sol.del_flg) in ('N', null)
            and trim(cnc.del_flg) in ('N', null)
            and trim(gct.del_flg) in ('N', null)
    )

where
    eod_date_rank = 1
    and GLSH_SET = 1

order by
    bank_id,
    sol_id,
    tran_currency,
    glsh_code,
    book_type desc,
    account_number,
    transaction_date;

EXIT WHEN SL_Ctr > Date_Diff;

END LOOP;  
END;

每当我运行它时,Toad 总是抛出错误,指向底部的END LOOP 行,说:

PLS-00103:在预期以下情况之一时遇到符号“文件结尾”: ( begin case 为 goto 声明 end 异常退出 if loop mod null pragma raise return select update while with

我知道我仍然需要在代码中添加一些内容,但我不知道它是什么。而且我也知道代码在某些方面是不完整的,因为查询本身仍然存在硬编码的东西。现在,我只想让代码用硬编码的东西显示数据。

我们将不胜感激,如果您需要有关查询的更多信息,请随时询问。

【问题讨论】:

注释掉 EXIT WHEN SL_Ctr > Date_Diff;线。 FOR 循环中不需要它。 @AsfakulIslam 我删除了它,我仍然得到同样的错误。 为什么要自愿执行此语句四次,而一次对所有日期执行一次就行了? @RobvanWijk 因为查询中有一部分使事情复杂化。也就是说,获取beg_tran_date_balend_tran_date_bal。相信我,我问过的每个人都建议我使用BETWEEN-AND,我告诉他们这不适合这个特定的查询。 我明白你的意思。这段代码几乎没有问题。您将字符串分配给日期变量,EXIT 语句是多余的,并且您从 EAB 表中选择了多次。为什么不从头开始,从您需要哪些表中的哪些数据开始呢?这样你可能会得到更好的答案。 【参考方案1】:

你写道:

FOR SL_Ctr in 1 .. Date_Diff
LOOP
select *
    from (
      big select
    )

where
    eod_date_rank = 1
    and GLSH_SET = 1

order by
    bank_id,
    sol_id,
    tran_currency,
    glsh_code,
    book_type desc,
    account_number,
    transaction_date;

EXIT WHEN SL_Ctr > Date_Diff;

END LOOP;
END;

在pl/sql中你不能这样使用SQL,你需要选择变量或者使用像游标这样的东西来选择使用它作为隐式游标。更改循环内的选择以将结果分配给变量。

见 DEVELOPER: PL/SQL Practices On BULK COLLECT

另一种写作方式可能是:

FOR SL_Ctr in 1 .. Date_Diff
LOOP
   for i in (
              select *
                from (
                        big select
                     )

where
    eod_date_rank = 1
    and GLSH_SET = 1

order by
    bank_id,
    sol_id,
    tran_currency,
    glsh_code,
    book_type desc,
    account_number,
    transaction_date
)
   loop
      dbms_output.put(line (i.bank_id||' '||i.bank_description);
   end loop;

EXIT WHEN SL_Ctr > Date_Diff;

END LOOP;
END;

【讨论】:

你建议我怎么做?而且,将结果分配给变量后,如何显示现在在变量中的结果?

以上是关于FOR LOOP 脚本未运行的主要内容,如果未能解决你的问题,请参考以下文章

如何为“For Loop”运行 gevent 池?

Jquery For Loop 结束代码

脚本的时间部分(运行时间)

bash/expect/loop - 如何循环执行 telnet 的简单 bash 脚本

如何解决 PHP For loop IN 内存问题

图像未出现在 Django 模板 For Loop 中