return 来自同一包中的过程的特定事物的函数

Function to return a specific thing from a procedure that are in the same package

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

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...]

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

I am thinking to have the procedure modify the p_min and p_max variables and have the functions just return the modified variables, can I do this?

当然;尽管尚不清楚何时应调用该过程。假设您需要从包外部调用它并且函数只是 return 当前状态,您还需要规范来包含该过程:

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;
/

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

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<>fiddle

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

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

How can I pass the parameters from the functions to the procedure, in order to get the minimum and the maximum values from the functions parameter?

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

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<>fiddle

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

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

但这是一个练习,所以...