【问题标题】:How to update a table using cursor如何使用游标更新表
【发布时间】:2020-09-14 20:50:03
【问题描述】:

如果今天的日期在表 ABC 的 start_date 和 end_date 之间,我需要编写一个过程来更新表 Xyz 的列。

table ABC

    fin_cycle    start_date   end_date    account_class
    ----------------------------------------------------

    F2018        27-05-2020    29-05-20    2003

table xyz
account_no    account_class  ac_no_dr

1234           2003             Y

当我今天运行程序时,如果今天的日期在表 ABC 的 start_date 和 end 日期之间,那么程序会将列 ac_no_dr 更新为 Y,否则它将更新列为 N。我已经准备了这个框架。

Create Or Replace PROCEDURE pr_no_debit
     Cursor c_Today(start_date, end_Date) is
     Select Today from sttm_branch  where today between start_Date and end_Date;

   l_No_Debit_List   ABC%ROW_TYPE;
   Begin



     For c_Today(l_No_Debit_List.start_Date,l_No_Debit_List.end_Date) Loop  


       Update XYZ set ac_no_DR='Y' where account_class=l_No_Debit_List.account_class;

   End Loop;

     -- At the end of the period Change No_Debit to 'N'

   End pr_no_debit;   

【问题讨论】:

  • 这段代码没有意义。 l_No_Debit_List 没有值。
  • 那么我该如何编写这个程序..请帮助..
  • update XYZ x set ac_no_DR='Y' where (select count(*) from ABC a where a.account_class=x.account_class and trunc(sysdate) between a.start_date and a.end_date) > 0

标签: oracle plsql


【解决方案1】:

这是一个选项:merge。 (今天是 27.05.2020,介于存储在 abc 表中的开始日期和结束日期之间)。

样本数据:

SQL> select * From abc;

FIN_C START_DATE END_DATE   ACCOUNT_CLASS
----- ---------- ---------- -------------
F2018 27.05.2020 29.05.2020          2003

SQL> select * From xyz;

ACCOUNT_NO ACCOUNT_CLASS A
---------- ------------- -
      1234          2003 

合并语句:

SQL> merge into xyz a
  2    using (select account_class,
  3                  case when sysdate between start_date and end_date then 'Y'
  4                       else 'N'
  5                  end ac_no_dr
  6           from abc
  7          ) x
  8    on (a.account_class = x.account_class)
  9    when matched then update set a.ac_no_dr = x.ac_no_dr;

1 row merged.

结果:

SQL> select * From xyz;

ACCOUNT_NO ACCOUNT_CLASS A
---------- ------------- -
      1234          2003 Y

SQL>

底线:您不需要过程或循环(效率低下),因为所有事情都可以通过一条 SQL 语句完成。


如果 - 正如您所评论的 - 必须是一个过程,也没有问题:

create or replace procedure p_merge as
begin
  merge into xyz a
  using (select account_class,
                case when sysdate between start_date and end_date then 'Y'
                     else 'N'
                end ac_no_dr
         from abc
        ) x
  on (a.account_class = x.account_class)
  when matched then update set a.ac_no_dr = x.ac_no_dr;
end;
/

【讨论】:

  • 我需要一个程序,因为我们需要通过一个调度程序来运行它,该调度程序将在每次 EOD 之后自动运行。
  • 好的,没问题。如果您不知道如何根据某些语句制作程序,我已经为您完成了 - 请看一下。
  • 我不能使用 sysdate ,在我们的应用程序中的每个 eod 之后,日期都会在表中更新,即 sttm_branch..我们需要从这个表中获取今天的日期..
  • 所以不要使用 SYSDATE 而是从你的表中获取日期。那有什么问题?我不知道 STTM_BRANCH 长什么样。
猜你喜欢
  • 2011-06-18
  • 1970-01-01
  • 2016-10-08
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 2012-10-23
  • 2016-01-05
  • 1970-01-01
相关资源
最近更新 更多