打开游标以基于oracle中同一表的其他列值获取和更新表的列值
我必须根据下面的逻辑更新表中的最后2列,该逻辑有42列打开游标以基于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
- C42的字段值(在下式中用N代替)=(“第一列位置为空/无值”-1)
- C41的字段值=C(N)列的字段值,其中N=(列“C42”的值减去1)
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