簡體   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