繁体   English   中英

oracle调用存储过程里面选择

[英]oracle call stored procedure inside select

我正在处理一个查询(一个SELECT),我需要在表中插入这个结果。 在进行插入之前,我有一些检查要做,如果所有列都有效,我将进行插入。

检查在存储过程中完成。 在其他地方也使用相同的程序。 所以我在考虑使用相同的程序进行检查。

该程序执行检查并插入值即可。

我试图在我的SELECT中调用该过程,但它不起作用。

SELECT field1, field2, myproc(field1, field2)

from MYTABLE.

这种代码不起作用。

我认为可以使用游标完成,但我想避免使用游标。 我正在寻找最简单的解决方案。

任何人,任何想法?

使用PL / SQL循环:

BEGIN
   FOR c IN (SELECT field1, field2 FROM mytable) LOOP
       my_proc(c.field1, c.field2);
   END LOOP;
END;

SQL只能使用投影中的函数:它需要返回值的东西。 所以你将不得不写一些函数。 这是坏消息。 好消息是,您可以在存储过程中重复使用所有投资。

这是一个强制执行完全公正的业务规则的程序:只有经理才能获得高薪。

SQL> create or replace procedure salary_rule
  2      ( p_sal in emp.sal%type
  3        , p_job in emp.job%type)
  4  is
  5      x_sal exception;
  6  begin
  7      if p_sal > 4999 and p_job != 'MANAGER' then
  8          raise x_sal;
  9      end if;
 10  exception
 11      when x_sal then
 12          raise_application_error(-20000, 'Only managers can earn that much!');
 13  end salary_rule;
 14  /

Procedure created.

SQL>

因为它是一个过程,我们不能在SELECT语句中使用它; 我们需要将它包装在一个函数中。 此函数只调用存储过程。 它返回输入参数P_SAL。 换句话说,如果工资有效(根据规则),它将被退回。 否则,该函数将重新抛出存储过程的异常。

SQL> create or replace function validate_salary
  2      ( p_sal in emp.sal%type
  3        , p_job in emp.job%type)
  4      return emp.sal%type
  5  is
  6  begin
  7      salary_rule(p_sal, p_job);
  8      return p_sal;
  9  end validate_salary;
 10  /

Function created.

SQL>

该函数必须返回一个我们想要插入表中的值。 它不能返回一些毫无意义的短语,如“薪水好”。 此外,如果我们想要验证两个列,我们需要为每个列分别使用一个函数,即使它们之间存在关系,我们也使用相同的存储过程来验证它们。 适用于DETERMINISTIC关键字。

这是测试:管道工无法获得5000个spondulicks ....

SQL> insert into emp
  2      (empno
  3      , ename
  4      , job
  5      , deptno
  6      , sal )
  7  select
  8      emp_seq.nextval
  9      , 'HALL'
 10      , 'PLUMBER'
 11      , 60
 12      , validate_salary(5000, 'PLUMBER')
 13  from dual
 14  /
    , validate_salary(5000, 'PLUMBER')
      *
ERROR at line 12:
ORA-20000: Only managers can earn that much!
ORA-06512: at "APC.SALARY_RULE", line 12
ORA-06512: at "APC.VALIDATE_SALARY", line 7


SQL>

......但管理者可以(因为他们应得):

SQL> insert into emp
  2      (empno
  3      , ename
  4      , job
  5      , deptno
  6      , sal )
  7  select
  8      emp_seq.nextval
  9      , 'HALL'
 10      , 'MANAGER'
 11      , 60
 12      , validate_salary(5000, 'MANAGER')
 13  from dual
 14  /

1 row created.

SQL>

请注意,抛出的异常对于此工作至关重要。 我们不能在SQL语句中写一些奇怪的IF SALARY IS VALID THEN INSERT逻辑。 因此,如果存储过程没有引发异常但是返回一些wimpy错误状态,则包装函数将必须解释输出并抛出其自己的异常。

您不能在SELECT语句中使用存储过程。 你可以使用它的功能。

据我所知,你在SP中调用insert,所以考虑到你可以在函数体中使用INSERT / UPDATE。 但是如果你需要做一些检查,你可以使用将执行该检查的函数并在select语句中使用该函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM