如何在Perl中编写代码,用两列的运行总数和总和更新Oracle SQL表?

64jmpszr  于 2023-06-22  发布在  Oracle
关注(0)|答案(1)|浏览(91)

我对Perl编程语言非常不熟悉,并且被赋予了用运行总数和列DEBIT和CREDIT的总和填充Oracle SQL表的任务。当我尝试加载测试文件csv时,运行的total和sum列没有正确加载。
我尝试创建一个子例程来填充运行的total和sum_of_debit credit列:

sub running total
{
my $sql=<<UPDATESQL;
    UPDATE liq.ecb_stat s
    SET sum_of_debit_credit= debit-credit
    WHERE s.sum_of_debit_credit IS NULL
;

    UPDATE liq.ecb_stat s
    SET running_total= {SELECT SUM(sum_of_debit_credit) OVER(ORDER BY settlement_time_stamp)
    FROM liq.ecb_stat s2 
    WHERE s.settlement_time_stamp=s2.settlement_time_stamp)
    where s.running_total IS NULL
    UPDATESQL
}

理想情况下,这应该返回正确的值,但到目前为止还没有。

tzcvj98z

tzcvj98z1#

您的SQL无效(我们不使用{ },而是使用( )进行子查询,并且OVER子句将返回多行,这违反了=表达式中的子查询必须仅返回一行的规则,所以我知道您尚未实际执行这些更新。
如果您遇到Perl问题,其他人可以帮助您解决这个问题,使您能够真正向数据库发送调用。但是一旦你弄清楚了,你还需要解决坏的SQL,这是一个Oracle的问题。
要获得运行总数,您必须在聚合中使用ROWS BETWEEN窗口,并且要获得合理的性能,您根本不应该在SET子句的子查询中尝试这样做。你最好使用MERGE,像这样:

MERGE INTO liq.ecb_stat tgt
USING (SELECT ROWID row_id,
              SUM(sum_of_debit_credit) OVER (ORDER BY settlement_time_stamp ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) running_total
         FROM liq.ecb_stat) src
   ON (tgt.ROWID = src.row_id)
 WHEN MATCHED THEN UPDATE SET tgt.running_total = src.running_total

您也可以将这两个操作合并为一个:

MERGE INTO liq.ecb_stat tgt
USING (SELECT ROWID row_id,
              debit - credit sum_of_debit_credit,
              SUM(debit - credit) OVER (ORDER BY settlement_time_stamp ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) running_total
         FROM liq.ecb_stat) src
   ON (tgt.ROWID = src.row_id)
 WHEN MATCHED THEN UPDATE tgt.running_total = src.running_total,
                          tgt.sum_of_debit_credit = src.sum_of_debit_credit

相关问题