Return 使用 DBI 从游标 FOR LOOP 计算得到的值

Return value from cursor FOR LOOP calculation using DBI

我正在尝试了解如何使用 DBI 从涉及游标 FOR LOOP 的 SQL 查询中 return 计算值。例如,我使用加载到 Oracle 数据库 (v19c) 中的 mtcars 数据集。它看起来像这样:

head(DBI::dbGetQuery(con, "SELECT * FROM TEST.MTCARS"))

#        MANUFACTURER  MPG CYL DISP  HP DRAT    WT  QSEC VS AM GEAR CARB       
# 1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
# 2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
# 3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
# 4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
# 5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
# 6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

现在,举个例子,假设我想对 MPG 进行迭代求和。我意识到我可以简单地使用 SUM 函数而不是循环,但这里的求和过程是另一个函数的占位符所以为了一个简单的例子而让我幽默!

下面,我声明了我的 运行 总变量 bar,然后遍历 MTCARS table 的 MPG 列,将每个 MPG 值添加到 运行 总和。当循环结束时,我有一个我想要 return 的总数,但我不知道该怎么做。 RETURN 似乎只有 return 个整数,所以这里没有意义。

tmp <- DBI::dbGetQuery(con,
"DECLARE
  bar NUMBER:=0;

BEGIN
  FOR foo IN (SELECT MPG FROM TEST.MTCARS)
  LOOP
    bar := bar + foo.MPG;
  END LOOP;
  
  DBMS_OUTPUT.PUT_LINE(bar);
END;")

tmp
#[1] TRUE

我应该如何 return 从上面的计算中得到一个值?对于这个例子,我希望得到值 642.9,但我得到了 TRUE。

就像我在评论中所说的那样,这是一种方法(我的示例在 scott@hr 上):

create or replace type sum_type is table of number;

create or replace function your_sum_fun
return sum_type PIPELINED is
    v_sum number:=0;
begin
    for i in (SELECT salary FROM employees)loop
       v_sum:=v_sum+i.salary;
    end loop;
    pipe row (v_sum);
    RETURN;
end;
select * from table(your_sum_fun);

create or replace function your_sum_fun
return sum_type PIPELINED is
    v_sum number:=0;
begin
    select sum(salary) into v_sum from employees;
    pipe row (v_sum);
    RETURN;
end;