2010-05-19 107 views
13

我正在查询(SELECT),我需要将这个结果插入到表中。 在插入之前,我有一些检查要做,如果所有的列都有效,我会做插入。oracle中调用存储过程select

检查在存储过程中完成。其他地方也使用相同的程序。 所以我想使用相同的程序来做我的检查。

该程序执行检查并插入值都是OK。

我尝试调用我的SELECT内部的过程,但它不起作用。

SELECT field1, field2, myproc(field1, field2) 

from MYTABLE. 

这种类型的代码不起作用。

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

任何人,任何想法?

回答

25

使用PL/SQL循环:

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

这是我需要的。谢谢。 – 2010-05-19 12:54:18

0

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

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

+0

是的,这将是最终的解决方案,但我想使用现有的SP,因为它是大型项目的一部分,我不想做新功能。这将是更难mantain。 – 2010-05-19 12:02:06

6

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错误状态,则包装函数将不得不解释输出并抛出它自己的异常。

+0

实际上,我的存储过程执行插入操作。所以我不能使用插入到选择。 – 2010-05-19 12:49:42