打开游标以基于oracle中同一表的其他列值获取和更新表的列值

打开游标以基于oracle中同一表的其他列值获取和更新表的列值,oracle,plsql,sql-update,oracle12c,database-cursor,Oracle,Plsql,Sql Update,Oracle12c,Database Cursor,我必须根据下面的逻辑更新表中的最后2列,该逻辑有42列 C42的字段值(在下式中用N代替)=(“第一列位置为空/无值”-1) C41的字段值=C(N)列的字段值,其中N=(列“C42”的值减去1) 注意:表值的设置方式是,当在列中遇到第一个空值时;在任何特定记录中,下面的其他列肯定为空。该表有大约100K条记录,它是一个中间表,上面的计算每周重复一次,新值填充在表中,最后两列将每周计算一次 例如: C42 = C19 ( 20 - 1) C41 = C(20) when 20 col

我必须根据下面的逻辑更新表中的最后2列,该逻辑有42列

  • C42的字段值(在下式中用N代替)=(“第一列位置为空/无值”-1)
  • C41的字段值=C(N)列的字段值,其中N=(列“C42”的值减去1)
注意:表值的设置方式是,当在列中遇到第一个空值时;在任何特定记录中,下面的其他列肯定为空。该表有大约100K条记录,它是一个中间表,上面的计算每周重复一次,新值填充在表中,最后两列将每周计算一次

例如:

C42 = C19   ( 20 - 1) 

C41 = C(20) when 20 columns have some value and 21st column is null

尝试创建存储过程并打开游标以获取要计算的值,但在创建逻辑和基于逻辑更新每一行时遇到问题。有人能提出一种有效的方法来执行上述计算逻辑并更新每个记录吗。提前感谢

如果我理解您在做什么,您不需要PL/SQL,您只需要使用coalesce和case表达式进行简单的更新-无可否认,两者都有很多术语,所以有点笨拙

使用一个非常简化的表,只需担心四列,再加上要更新的第41列和第42列:

create table your_table (c1 number, c2 number, c3 number, c4 number, c41 number, c42 number);
insert into your_table (c1, c2) values (11, 12);
insert into your_table (c1, c2, c3) values (23, 24, 25);
通过按相反顺序合并所有其他列,可以获得
c42
值:

coalesce(c4, c3, c2, c1)
或者在您的情况下:

coalesce(c40, c39, c38, c37, ..., c4, c3, c2, c1)
您可以使用大小写表达式获得该列的位置,如:

case
  when c40 is not null then 40
  when c39 is not null then 39
  ...
  when c4 is not null then 4
  when c3 is not null then 3
  when c2 is not null then 2
  when c1 is not null then 1
end;
您可以通过(使用我的简化表)进行查询以查看值:

您可以通过以下方式进行更新:

update your_table
set c41 = coalesce(c4, c3, c2, c1),
  c42 =
    case
      when c4 is not null then 4
      when c3 is not null then 3
      when c2 is not null then 2
      when c1 is not null then 1
    end;

2 rows updated.

select * from your_table;

        C1         C2         C3         C4        C41        C42
---------- ---------- ---------- ---------- ---------- ----------
        11         12                               12          2
        23         24         25                    25          3

如果这是你将要经常做的事情,那么你可以制作那些虚拟列,这样它们就会自动计算,并且总是最新的。

这还不是很清楚。您能否尝试更清楚地解释逻辑,并显示一些具有代表性的值的示例(但列数较少-可能是一个包含10列的MCVE来演示)?我认为您正在将一个设置为列位置,另一个设置为该列中的值,用于该行的最后一个非null…?感谢您的时间和努力。我必须为C41找到第二个NOTNULL值,但是使用了您的逻辑,并对我的解决方案进行了一些调整,结果成功了。
update your_table
set c41 = coalesce(c4, c3, c2, c1),
  c42 =
    case
      when c4 is not null then 4
      when c3 is not null then 3
      when c2 is not null then 2
      when c1 is not null then 1
    end;

2 rows updated.

select * from your_table;

        C1         C2         C3         C4        C41        C42
---------- ---------- ---------- ---------- ---------- ----------
        11         12                               12          2
        23         24         25                    25          3