oracle在select里面调用存储过程

发布于 2024-09-01 23:33:35 字数 363 浏览 3 评论 0原文

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

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

该过程进行检查并插入值一切正常。

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

SELECT field1, field2, myproc(field1, field2)

from MYTABLE.

这种代码不起作用。

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

有人有什么想法吗?

I'm working on a query (a SELECT) and I need to insert the result of this one in a table.
Before doing the insert I have some checking to do, and if all columns are valid, I will do the insert.

The checking is done in a stored procedure. The same procedure is used somewhere else too.
So I'm thinking using the same procedure to do my checks.

The procedure does the checkings and insert the values is all OK.

I tryied to call the procedure inside my SELECT but it does not works.

SELECT field1, field2, myproc(field1, field2)

from MYTABLE.

This kind of code does not works.

I think it can be done using a cursor, but I would like to avoid the cursors.
I'm looking for the easiest solution.

Anybody, any idea ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寂寞美少年 2024-09-08 23:33:43

不能在 SELECT 语句中使用存储过程。
您可以为此使用函数。

据我了解,您正在 SP 中调用 insert,因此请考虑您可以在函数体中使用 INSERT/UPDATE。但是,如果您需要执行一些检查,您可以使用将执行检查的函数,并在 select 语句中使用该函数。

You can't use stored procedures in SELECT statement.
You can use functions for that.

As I understand you are calling insert in your SP, so take into consideration that you can's use INSERT/UPDATE in function body. But if you need to do some checks you can use function which will do that checks and use that function in your select statement.

命比纸薄 2024-09-08 23:33:41

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 逻辑。因此,如果存储过程没有引发异常,而是返回一些微不足道的错误状态,则包装函数将必须解释输出并抛出自己的异常。

SQL can only use functions in the projection: it needs something which returns a value. So you are going to have to write some functions. That's the bad news. The good news is, you can re-use all the investement in your stored procedures.

Here is a procedure which enforces a completely just business rule: only managers can have a high salary.

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>

Because it is a procedure we cannot use it in a SELECT statement; we need to wrap it in a function. This function just calls the stored procedure. It returns the input parameter P_SAL. In other words, if the salary is valid (according to the rules) it will be returned. Otherwise the function will re-hurl the stored procedure's exception.

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>

The function has to return a value which we want to insert into our table. It cannot return some meaningless phrase like "salary okay". Also, if we want to validate two columns we need a separate function for each, even if there is a relationship between them and we use the same stored procedure to validate them both. Good use for the DETERMINISTIC keyword.

Here's the test: plumbers cannot earn 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>

... but managers can (because they deserve it):

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>

Note that the hurled exception is crucial to this working. We cannot write some bizarre IF SALARY IS VALID THEN INSERT logic in our SQL statement. So, if the stored procedure doesn't raise an exception but instead returns some wimpy error status the wrapping function will have to interpret the output and hurl its own exception.

ぽ尐不点ル 2024-09-08 23:33:40

使用 PL/SQL 循环:

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

use a PL/SQL loop:

BEGIN
   FOR c IN (SELECT field1, field2 FROM mytable) LOOP
       my_proc(c.field1, c.field2);
   END LOOP;
END;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文