如何在 plsql 中更新此函数?

Posted

技术标签:

【中文标题】如何在 plsql 中更新此函数?【英文标题】:How can I update this function in plsql? 【发布时间】:2013-05-23 00:07:10 【问题描述】:

此函数检查所有员工的工资是否在正确的最高和最低工资范围之间。我想更新它,以便它返回工资超出范围的员工 ID ?? 我尝试定义一个集合,但它一直给我错误。有什么想法吗??

create or replace function min_max return number as
cursor job_cur is
    select job_id, min_salary, max_salary from jobs;
cursor emp_cur(p_job_id jobs.job_id%type) is
    select employee_id, salary from employees where job_id = p_job_id;
Type id_table is table of number index by binary_integer;
return_id id_table;
i number := 1;
begin
for job_rec in job_cur loop
    for emp_rec in emp_cur(job_rec.job_id) loop
        if (emp_rec.salary > job_rec.max_salary)
            or (emp_rec.salary < job_rec.min_salary) then
            --return 0;
            return_id(i).emlpoyee_id := emp_rec.employee_id; // error here
            i := i+1;
        end if;
    end loop;
end loop;
--return 1;
return return_id;  // error here
end min_max;

这是更新后的代码,但它不起作用。错误: 错误(15,17):PL/SQL:语句被忽略。 错误(15,30):PLS-00487:对变量“NUMBER”的引用无效。 错误(21,5):PL/SQL:语句被忽略。 错误(21,12):PLS-00382:表达式类型错误。

【问题讨论】:

能否将 cmets 添加到实际发生错误的行中?很难跟上。 如果你想返回 id(s) - 多个 - 这意味着你需要返回一个 refcursor 到一个打开的结果集。不是数字。 或者你可以定义一个集合类型并返回它。 【参考方案1】:

如果你在函数外定义类型,函数可以返回一个集合。另外,不要循环两个游标。如果可以,请始终将 SQL 操作作为一组进行。通过这种方式,您可以获得更好的性能。

只要员工人数不太多,这行得通:

CREATE TYPE id_table AS TABLE OF NUMBER;

CREATE OR REPLACE FUNCTION min_max RETURN id_table AS
  l_emp_list id_table;
BEGIN
  SELECT e.employee_id 
    BULK COLLECT INTO l_emp_list
    FROM employees e 
   INNER JOIN jobs j ON j.job_id = e.job_id
   WHERE e.salary NOT BETWEEN j.min_salary AND j.max_salary;

  RETURN l_emp_list;
END;

由于某种原因,SQLFiddle 给了我一个错误,但这在我的数据库中有效。

【讨论】:

表示数据库是成批返回结果,而不是逐行返回。 Oracle 进行了高度优化,可以对集合而不是单个行进行操作。 docs.oracle.com/cd/B12037_01/appdev.101/b10807/…

以上是关于如何在 plsql 中更新此函数?的主要内容,如果未能解决你的问题,请参考以下文章

在 PLSQL 中,如何迭代更新一个非常大的表的字段?

如何从从 plsql 函数 ORACLE 返回的游标中进行选择

如何使用动态用户输入在 plsql 中使用函数/过程创建表

如何使用记录类型、对象和构造函数在 PLSQL 中给出多个输入值?

如何从 PLSQL 中的函数返回一组 NUMBERS,然后在 FOR LOOP 中使用它?

如何在 PLSQL Developer 中测试包含 DML 的 Oracle 函数?