首页 > 解决方案 > 我正在努力理解用户定义的函数,以及如何在查询中调用它们

问题描述

我必须创建一个 UDF 作为我作业的一部分。它对我们创建的内容是完全开放的,我选择创建一个函数,在给定 STAFF_ID 和 WEEK_NUM 时计算员工的总工资。

该功能的代码如下(请原谅格式化,我不确定格式化它的正确方法):

CREATE OR REPLACE FUNCTION CALCULATE_WAGES(FSTAFFID IN NUMBER, FWEEKNUM IN NUMBER)
RETURN NUMBER
IS
WAGES NUMBER(6,3);
STAFF_ID NUMBER;
HOURS_WORKED NUMBER;
MAX_HOURS NUMBER;
HOURLY_RATE NUMBER;
OVERTIME_RATE NUMBER;
WEEK_NUM NUMBER;

CURSOR C1 IS
    SELECT STAFF_ID, HOURS_WORKED, MAX_HOURS, HOURLY_RATE, OVERTIME_RATE, WEEK_NUM FROM STAFF_HOURS WHERE STAFF_ID = FSTAFFID AND WEEK_NUM = FWEEKNUM;

BEGIN

OPEN C1;
FETCH C1 INTO STAFF_ID, HOURS_WORKED, MAX_HOURS, HOURLY_RATE, OVERTIME_RATE, WEEK_NUM;

IF HOURS_WORKED > MAX_HOURS
THEN WAGES := (HOURLY_RATE * MAX_HOURS) + (HOURS_WORKED - MAX_HOURS) * OVERTIME_RATE;
ELSE WAGES := HOURLY_RATE * MAX_HOURS;
END IF;

CLOSE C1;

RETURN WAGES;

END;

当我在 sqldeveloper 中自行运行此函数时,此函数运行良好,如下所示以下是该表的数据类型。会弹出一个框让我输入参数,然后吐出返回值,这也是正确的。

这是STAFF_HOURS 表的屏幕截图。

所以现在我的表中充满了测试数据,以及一个接受两个参数并输出正确值的函数。

我现在遇到的问题是使用选择查询将该值放入表中。我到目前为止是这样的:

SELECT STAFF_ID, FIRST_NAME, LAST_NAME, HOURS_WORKED, MAX_HOURS, HOURLY_RATE, OVERTIME_RATE, WEEK_NUM, CALCULATE_WAGES(STAFF_ID, WEEK_NUM) AS "TOTAL DUE" FROM STAFF_HOURS;

我希望这样做是从表中选择所有行,然后在最后添加一个等于函数返回值的新行。然后,这将显示每个工作人员在该特定周应支付多少钱。

但是,我收到此错误:

ORA-06502: PL/SQL: numeric or value error: number precision too large
ORA-06512: at "O015596H.CALCULATE_WAGES", line 21
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.

我对 SQL 的了解不够,无法真正知道如何用谷歌搜索我的问题,所以我认为最好的办法是在这里解释我的问题,并希望有人能理解。

谢谢你的帮助!

标签: oracleplsql

解决方案


你知道这意味着什么吗?

WAGES NUMBER(6, 3);

这在小数点的左边有三位(6 - 3),在右边有三位,所以最大值为999.999。我猜这是你的问题的原因。(您可以在文档中了解数据类型。)

您可以忽略规模和精度,Oracle 代码应该可以工作。


推荐阅读