在 ORACLE 的 select 语句中从 PL/SQL 调用函数

Posted

技术标签:

【中文标题】在 ORACLE 的 select 语句中从 PL/SQL 调用函数【英文标题】:calling a function from PL/SQL in a select statement in ORACLE 【发布时间】:2014-08-19 13:42:15 【问题描述】:

这是我的 PL/SQL 函数部分。我正在尝试在 select 语句中使用该函数。例如,我们可以编写一个类似select count(column_name) from table_name 的查询。这里 count 是一个函数。我想像这样使用我自己的功能。我尝试过不同的方法(使用 PL/SQL 函数之外的函数,PL/SQL 函数内部的函数)。但在 PL/SQL 函数内部使用时会引发错误 PLS-00231:function 'GET_ANNUAL_COMP' may not be used in SQL,而在 PL/SQL 函数外部使用时会引发 ORA-00904 invalid identifier

我正在使用 oracle 11g。

declare
em_sal number(20);
em_comm employees.commission_pct%type; 
annual_salary number(10,4);

function get_annual_comp(sal in number, comm in number)
return number is
begin
return (sal*12 + comm*12);
end;
begin
select salary into em_sal from employees where employee_id=149;
select commission_pct into em_comm from employees where employee_id=149;

annual_salary := get_annual_comp(em_sal,em_comm);

dbms_output.put_line('total salary '|| annual_salary);

select get_annual_comp(salary,commission_pct) from employees where department_id=90;
end;
/

【问题讨论】:

要与 SQL 一起使用,该函数已使用 CREATE OR REPLACE ... 编译为 DB 对象 所以错误在 PL/SQL 中准确地说,因为它看到了范围在它的块中。当我们从外部尝试时,它甚至无法识别,因此invalid identifier。因此,您必须使用 SQL 创建函数 globally PL/SQL匿名块中真的需要这个函数吗? @MaheswaranRavisankar btw,在 12c 中不再需要,您可以在 sql 中内联 plsql 函数 太棒了,感谢您的信息! @beherenow 。我没有机会探索 12c !! @MaheswaranRavisankar oracle.com/technetwork/issue-archive/2013/13-sep/… 【参考方案1】:

在适当的模式(将运行匿名块的相同模式)中编译函数,如下所示:

CREATE OR REPLACE FUNCTION GET_ANNUAL_COMP(
    sal  IN NUMBER,
    comm IN NUMBER)
  RETURN NUMBER
IS
BEGIN
  RETURN (sal*12 + comm*12);
END;

使用与函数相同的架构,运行匿名块:

DECLARE
  em_sal NUMBER(20);
  em_comm employees.commission_pct%type;
  annual_salary NUMBER(10,4);
BEGIN
  SELECT salary INTO em_sal FROM employees WHERE employee_id=149;
  SELECT commission_pct INTO em_comm FROM employees WHERE employee_id=149;
  annual_salary := get_annual_comp(em_sal,em_comm);
  dbms_output.put_line('total salary '|| annual_salary);
  SELECT SUM(get_annual_comp(salary,commission_pct)) into annual_salary
  FROM employees
  WHERE department_id=90;
  dbms_output.put_line('department annual salary '|| annual_salary);
END;
/

【讨论】:

【参考方案2】:

全局创建函数。还要确保该函数是在相同的架构中创建的,并且登录用户在架构中具有必要的权限。

【讨论】:

以上是关于在 ORACLE 的 select 语句中从 PL/SQL 调用函数的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询的 SELECT 子句中 Oracle PL/SQL 语句的延迟评估

如何从 oracle pl sql 中的包主体内的 select 语句中捕获特定列

PL/SQL:, 如何将变量传递给 SELECT 语句并返回所有结果行

在 oracle 数据库问题中从另一个调用 pl/sql

减少oracle PL/SQL语句

oracle SQL语句中怎么样调用存储过程