2017-05-26 79 views
-3

功能我有一個表人員enter image description here創建循環甲骨文

我想,當我打電話功能select functionname(443) from dual它返回序列staff_id創建功能。

例如

1. select functionname(443) from dual return 863; 
2. select functionname(443) from dual return 864; 
3. select functionname(443) from dual return 866; 
. 
. 
. 
n. select functionname(443) from dual return 6733; 

和863; 864; 866 ... 6733

+1

這不是很清楚。你有一張表,但你想要一個函數來對這張表進行查詢,但是在一個雙重查詢中?你不能簡單地查詢你的表嗎?這個函數的返回類型應該是什麼。此外,請發佈數據作爲格式化文本,[不截圖](http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-問一個問題/ 285557#285557) – Aleksej

+0

那麼你想從一個你不從純SQL獲得的函數中獲得什麼好處?從dept_id = 443'的staff中選擇staff_id? – APC

+0

當我第一次調用函數時,首先返回staff_id = 1; 當我第二次調用函數時,它首先返回staff_id = 2; 當我n次調用函數時,首先返回staff_id = n; 然後循環再次重複 – Tiko

回答

2

「時我第一次呼叫功能它返回第一staff_id = 1;當我第二次呼叫功能它返回第一staff_id = 2;當我n個時間呼叫功能它返回第一staff_id = N;且之後,循環再次重複「

程序思維通常是一種代碼味道。關係數據庫用於處理數據集。但是,到底什麼時候,讓我們享受一些午餐時間的樂趣吧:

我們需要一個包,因爲包變量允許我們維護函數調用的狀態。 (有這樣做的其他方式,如上下文的命名空間,但一個包是容易實現的。)

create or replace package pkg_test is 
    function get_staff_id (p_dept_id number) return number; 
end pkg_test ; 
/

create or replace package body pkg_test is 
    -- variables to maintain state across function calls 
    ids_nt dbms_utility.number_array; 
    idx number := 0; 
    last_dept_id number := 0; 

    function get_staff_id (p_dept_id number) return number 
    is 
     return_value number; 
    begin 
     if idx = 0 
     or last_dept_id != p_dept_id 
     then 
      select staff_id 
      bulk collect into ids_nt 
      from staff 
      where dept_id = p_dept_id; 

      last_dept_id := p_dept_id; 
      idx := 0; 
     end if; 

     idx := idx + 1; 
     return_value := ids_nt(idx); 
     if idx = ids_nt.count() then 
      idx := 0; 
     end if; 

     return return_value; 
    end get_staff_id ; 
end pkg_test ; 
/

注意

  1. 保持這樣的全局狀態一般不考慮好實踐。它在這裏工作,但在更復雜的過程中,狀態很容易被我們不期望的調用改變。
  2. 狀態保持在會話級別。兩個單獨的會話將獲得兩組數據,而不是一個交錯組。所以對於使用連接池的應用程序來說這不是一個好的實現。
+0

當我調用它時,一個問題,但改變dep_id,它返回null – Tiko

+0

@Tiko - 星期五午餐時間有趣的問題是它往往導致錯誤:)我們需要重置計數器時重新填充數組。我已經修復了代碼,現在就試用它。 – APC

0

我打算做一個假設,你想要做的是調用一個函數返回所有您傳遞的dept_id的staff_ids。這是一個假設,因爲您根本不清楚問題中的要求。

CREATE OR REPLACE TYPE staff_res_t AS OBJECT (staff_id NUMBER) 

CREATE TYPE staff_res_tab AS TABLE OF staff_res_t 

CREATE OR REPLACE FUNCTION getdept(in_dept NUMBER) 
    RETURN staff_res_tab 
    PIPELINED 
IS 
    CURSOR c_staff 
    IS 
     SELECT staff_id 
     FROM you_table 
     WHERE dept = in_dept; 

    out_rec staff_res_t := staff_res_t(NULL); 
BEGIN 
    FOR rec_staff IN c_staff 
    LOOP 
     out_rec.staff_id := rec_staff.staff_id; 
     PIPE ROW (out_rec); 
    END LOOP; 

    RETURN; 
END;  

SELECT * FROM TABLE(getdept(443))