从同一包中的过程返回特定事物的函数[关闭]

Posted

技术标签:

【中文标题】从同一包中的过程返回特定事物的函数[关闭]【英文标题】:Function to return a specific thing from a procedure that are in the same package [closed] 【发布时间】:2020-03-20 15:56:14 【问题描述】:

我有一个计算 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...]

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

【问题讨论】:

好吧,至少给我们看看你写的东西,我们也许能帮上忙。 “在过程中找到请求的值”实际上没有意义。如果程序只在内部计算和使用它们,作为局部变量,那么就没有办法看到它们。如果该过程将它们公开为 OUT 变量,则只需调用该过程。如果它设置了一个全局变量,那么只需引用它。没有足够的信息来真正帮助您 - 显示一些代码可能会有所帮助。 @AlexPoole 在包体中使用 2 个局部变量,该过程将只修改这 2 个变量,函数将返回这些变量。我觉得是这样的 过程本地,还是在包级别(正文或规范)定义?请edit your question 显示minimal reproducible example。 @AlexPoole 添加了一些代码 【参考方案1】:

我正在考虑让程序修改 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<>fiddle

如果您需要来自 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<>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

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

【讨论】:

这看起来不错,感谢您为帮助我理解所做的努力。如何将函数中的参数传递给过程,以便从函数参数中获取最小值和最大值? 您是否要获取两个函数参数之间的最小值/最大值?即复制了内置的least()greatest() 函数已经做了什么?如果是这样 - 为什么;全局变量的意义何在? 只是为了练习在 plsql 中编写代码。我需要做什么才能从函数传递参数,以便程序可以比较它们并将最小值和最大值分配给 p_min 和 p_max 变量? 我认为以下内容可能更接近 OP 正在寻找的内容。 (我将作为答案发布,但问题已关闭,不知道为什么。)该过程应该有两个 IN 和两个 OUT 参数。两个函数都在它们的执行块中调用过程;每个返回 OUT 参数之一。复制LEAST()GREATEST() 的目的只是练习——这听起来不像是生产问题,而是学习问题。 是的,我说“如果你正在这样做,那么你根本不需要包变量,你的过程可以使用 OUT 变量”。我想我可以添加一个示例,但它已经太长了…… OP 说这是为了练习。在提供了更多信息后,我正要撤回投票,所以它被关闭了。

以上是关于从同一包中的过程返回特定事物的函数[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

定义只能从同一包中的后代访问的方法

Python:尝试从同一包中导入模块时出现“ModuleNotFoundError”

在 Python 3 中从同一包内和包外导入模块

linux读串口一直返回最后一包数据

从函数返回时访问数组元素

1.1.1函数式编程