我正在 oracle 19c 中创建一个 PL SQL 函数来查找两个数字中的最大值

Posted

技术标签:

【中文标题】我正在 oracle 19c 中创建一个 PL SQL 函数来查找两个数字中的最大值【英文标题】:I am creating a PL SQL function in oracle 19c to find largest among two numbers 【发布时间】:2021-07-11 14:42:26 【问题描述】:

我创建了名为 findLargest 的函数,如下所示: 我正在尝试调用它,但我收到如下所示的错误:

SQL> CREATE FUNCTION findLargest (x IN NUMBER, y IN NUMBER)
  2  RETURN NUMBER
  3  IS z NUMBER;
  4  BEGIN
  5  IF x > y THEN
  6     z:= x;
  7  ELSE
  8     z:=y;
  9  END IF;
 10  RETURN z;
 11  END;
 12  /

Function created.

你能告诉我调用块有什么问题吗?

SQL> DECLARE
  2  a:= 10;
  3  b := 20;
  4  c := 0;
  5  BEGIN
  6  c := findLargest(a,b);
  7  dbms_output.put_line ('Largest number is : '|| c);
  8  END;
  9  /
a:= 10;
 *
ERROR at line 2:
ORA-06550: line 2, column 2:
PLS-00103: Encountered the symbol "=" when expecting one of the following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table columns long
double ref char time timestamp interval date binary national
character nchar
The symbol "<an identifier>" was substituted for "=" to continue.
ORA-06550: line 3, column 3:
PLS-00103: Encountered the symbol "=" when expecting one of the following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table columns long
double ref char time timestamp interval date binary national
character nchar

我第一次在 *** 上发布问题。所以如果你发现一些奇怪的东西,请与我裸露!

【问题讨论】:

简单地使用greatest()有什么问题? DECLARE部分,当你声明一个变量时,你还必须声明它的数据类型——不管你是否给它赋值.即使认为a := 10 应该向解析器建议您的意思是a 作为number 数据类型,但语言不允许这样做;你必须声明为a number := 10 @a_horse_with_no_name - 作为学习过程的一部分,我似乎很清楚(尽管对你来说可能不是)OP 正在练习编写函数。如果是这样的话,那么“简单地使用greatest()有什么问题”就变得显而易见了。 这是她的作业。 @mathguy 有道理。 【参考方案1】:

你只是忘记了变量名后面的数据类型:

a INTEGER := 10;

【讨论】:

【参考方案2】:

只是为了娱乐,这样您就不必只选择两个数字中的最大值,您可以将集合传递给函数,按降序对值进行排序并选择第一个。像这样的:

SQL> create or replace function f_great (par_list in sys.odcinumberlist)
  2    return number
  3  is
  4    retval number;
  5  begin
  6    select cv
  7      into retval
  8      from (select column_value cv,
  9              row_number() over (order by column_value desc) rn
 10            from table(par_list)
 11           )
 12      where rn = 1;
 13    return retval;
 14  end;
 15  /

Function created.

SQL> select f_great(sys.odcinumberlist(1, 5, 23, 18, -2)) result_1,
  2         f_great(sys.odcinumberlist(-100, -2.1, -2.2)) result_2
  3  from dual;

  RESULT_1   RESULT_2
---------- ----------
        23       -2,1

SQL>

【讨论】:

【参考方案3】:

你的问题是你没有声明变量的数据类型:

DECLARE
  a NUMBER := 10;
  b NUMBER := 20;
  c NUMBER;
BEGIN
  c := findLargest(a,b);
  dbms_output.put_line ('Largest number is : '|| c);
END;
/

(您也不需要为c 变量赋值。)

您可以通过消除中间变量以更简单的方式编写调用块:

BEGIN
  dbms_output.put_line ('Largest number is : '|| findLargest(10,20));
END;
/

但是,如果您传递 NULL 值,则您的函数会出现问题:

BEGIN
  dbms_output.put_line ('Largest number is : '|| findLargest(10,NULL));
  dbms_output.put_line ('Largest number is : '|| findLargest(NULL,10));
END;
/

输出:

Largest number is : 
Largest number is : 10

问题在于10 &gt; NULLNULL &gt; 10 都不会返回真实值,因此在这两种情况下都会返回y 值而不是返回NULL 值。

您可以通过检查 NULL 值(并使用 CASE 语句且无中间变量)来解决此问题:

CREATE FUNCTION findLargest (x IN NUMBER, y IN NUMBER)
  RETURN NUMBER
IS
BEGIN
  RETURN CASE
         WHEN x IS NULL OR y IS NULL
         THEN NULL
         WHEN x > y
         THEN x
         ELSE y
         END;
END;
/

然后:

BEGIN
  dbms_output.put_line ('Largest number is : '|| findLargest(10,20));
  dbms_output.put_line ('Largest number is : '|| findLargest(10,NULL));
  dbms_output.put_line ('Largest number is : '|| findLargest(NULL,10));
END;
/

输出:

Largest number is : 20
Largest number is : 
Largest number is : 

db小提琴here

【讨论】:

以上是关于我正在 oracle 19c 中创建一个 PL SQL 函数来查找两个数字中的最大值的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle pl/sql 中创建或替换表

Oracle ApeX (PL/SQL) - 从 JavaScript 变量中创建绑定变量

由于 Oracle DB 从 12c 升级到 19c,对现有 SQL、PL/SQL 脚本和数据模型有何影响?

PL/SQL/Oracle DB:过程:ORA-29013:SSL MAC 验证失败(数据库 19c)

直接使用java在Oracle数据库中创建函数

OBIEE 12.2.1.4.0 兼容 Oracle 数据库 19c?