首页 > 解决方案 > 从同一包中的过程返回特定事物的函数

问题描述

我有一个计算 2 个数字的最小和最大数量的过程,我需要编写一个函数,该函数将返回该过程中的最小数量,另一个函数将返回同一过程中的最大数量。过程和功能在同一个包中。我需要调用该函数,该函数必须在过程中找到请求的值。到目前为止,我创建了包和包体,编写了过程,但我真的不知道如何编写函数以便从过程中检索相应的值。谁能帮我这个?

create or replace package min_max is
   p_min integer;
   p_max integer; 
   function f_min(n1 in integer, n2 in integer) return integer;
   function f_max(n1 in integer,n2 in integer) return integer;
end;

create or replace package body min_max is
  procedure do_all...]

我不知道如何从函数中获取参数以在过程中使用它们,我应该在定义过程之前放置函数签名吗?

标签: oraclestored-proceduresplsqlstored-functions

解决方案


我正在考虑让程序修改 p_min 和 p_max 变量并让函数只返回修改后的变量,我可以这样做吗?

当然; 虽然尚不清楚何时应该调用该过程。假设您需要从包外部调用它并且函数只返回当前状态,那么您也需要规范来包含该过程:

create or replace package min_max is
  p_min integer;
  p_max integer; 
  procedure do_all;
  function f_min(n1 in integer, n2 in integer) return integer;
  function f_max(n1 in integer,n2 in integer) return integer;
end;
/

然后让程序设置值(这里使用随机数,只是作为演示);并且函数只是返回它们:

create or replace package body min_max is

  procedure do_all is
  begin
    p_min := dbms_random.value(1, 100);
    p_max := dbms_random.value(500, 1000);
  end do_all;

  function f_min(n1 in integer, n2 in integer) return integer is
  begin
    -- do something with n1/n2?
    return p_min;
  end f_min;

  function f_max(n1 in integer, n2 in integer) return integer is
  begin
    -- do something with n1/n2?
    return p_max;
  end f_max;

end min_max;
/

然后调用该过程来设置值:

begin
  min_max.do_all;
end;
/

并一起或单独调用这些函数:

select min_max.f_min(0, 0), min_max.f_max(0, 0) from dual;

MIN_MAX.F_MIN(0,0) MIN_MAX.F_MAX(0,0)
------------------ ------------------
                59                987

db<>小提琴

如果您需要来自 PL/SQL 上下文而不是 SQL 上下文(即来自查询)的值,那么当您在包规范中声明变量时,您可以直接引用它们,例如:

begin
  dbms_output.put_line(min_max.p_min);
end;
/

如何将函数中的参数传递给过程,以便从函数参数中获取最小值和最大值?

您的过程需要参数,而您只需传递值。如果这就是它的全部用途,那么该过程可以是私有的。

create or replace package min_max is
  p_min integer;
  p_max integer; 
  function f_min(n1 in integer, n2 in integer) return integer;
  function f_max(n1 in integer,n2 in integer) return integer;
end;
/

create or replace package body min_max is

  procedure do_all (n1 in integer, n2 in integer) is
  begin
    p_min := least(n1, n2);
    p_max := greatest(n1, n2);
  end do_all;

  function f_min(n1 in integer, n2 in integer) return integer is
  begin
    do_all(n1, n2);
    return p_min;
  end f_min;

  function f_max(n1 in integer, n2 in integer) return integer is
  begin
    do_all(n1, n2);
    return p_max;
  end f_max;

end min_max;
/

然后:

select min_max.f_min(70, 900), min_max.f_max(70, 900) from dual;

MIN_MAX.F_MIN(70,900) MIN_MAX.F_MAX(70,900)
--------------------- ---------------------
                   70                   900

select min_max.f_min(30, 1), min_max.f_max(30, 1) from dual;

MIN_MAX.F_MIN(30,1) MIN_MAX.F_MAX(30,1)
------------------- -------------------
                  1                  30

您的变量也可以是私有的(使用任一版本)。

db<>fiddle,如上所述,但主体中的变量不是规范,因此它们是私有的。

但如果这就是你正在做的,那么你根本不需要包变量,你的过程可以使用 OUT 变量:

create or replace package min_max is
  function f_min(n1 in integer, n2 in integer) return integer;
  function f_max(n1 in integer,n2 in integer) return integer;
end;
/

create or replace package body min_max is

  procedure do_all (n1 in integer, n2 in integer, p_min out integer, p_max out integer) is
  begin
    if n2 >= n1 then
      p_min := n1;
      p_max := n2;
    else
      p_max := n1;
      p_min := n2;
    end if;  
    p_min := least(n1, n2);
    p_max := greatest(n1, n2);
  end do_all;

  function f_min(n1 in integer, n2 in integer) return integer is
    l_min integer;
    l_max integer;
  begin
    do_all(n1, n2, l_min, l_max);
    return l_min;
  end f_min;

  function f_max(n1 in integer, n2 in integer) return integer is
    l_min integer;
    l_max integer;
  begin
    do_all(n1, n2, l_min, l_max);
    return l_max;
  end f_max;

end min_max;
/

db<>小提琴

但是,你根本不需要这个包;您可以直接使用内置函数:

select least(70, 900), greatest(70, 900) from dual;

LEAST(70,900) GREATEST(70,900)
------------- ----------------
           70              900

select least(30, 1), greatest(30, 1) from dual;

LEAST(30,1) GREATEST(30,1)
----------- --------------
          1             30

但这是一种锻炼,所以...


推荐阅读