2012-12-03 51 views
3

這可能會發現有點愚蠢,但我想知道這是否可能。函數返回sys_refcursor從具有特定列的sql調用

我有返回SYS_REFCURSOR

CREATE OR REPLACE FUNCTION get_employee_details(p_emp_no IN EMP.EMPNO%TYPE) 
    RETURN SYS_REFCURSOR 
AS 
    o_cursor SYS_REFCURSOR; 
BEGIN 
    OPEN o_cursor FOR 
     SELECT EMPNO, 
      ENAME, 
      JOB, 
      MGR, 
      HIREDATE, 
      SAL, 
      COMM, 
      DEPTNO 
     FROM emp 
     WHERE EMPNO = p_emp_no; 

    RETURN o_cursor; 
-- exception part 
END; 
/

的功能,我可以使用

select get_employee_details('7369') from dual; 

是否有可能得到通過指定列名以上功能的結果得到的結果? 例如如果我想獲得ename或工資,我怎麼能在sql語句中指定而不使用plsql塊? 喜歡的東西

select get_employee_details('7369') <specific column> from dual; 
+0

這背後@NicholasKrasnov想法就是我會創造一個功能讓員工詳細信息,當我想只得到僱員的工資是否可以指定僅提取工資而不是所有列? 'double'選擇get_employee_details('7369')將返回在列的函數選擇列表中指定的所有列。 – user75ponic

回答

3

不,不與ref cursor可言,否則沒有創建SQL類型轉換返回到,像這樣的例子:http://dbaspot.com/oracle-server/9308-select-ref-cursor.html

create or replace type myType as object (
a int, 
b varchar2(10) 
) 
/

create or replace type myTable as table of myType; 
/

create or replace function f1 return myTable as 
l_data myTable := myTable(); 
begin 
for i in 1 .. 5 loop 
l_data.extend; 
l_data(i) := myType(i, 'Row #'||i); 
end loop; 
return l_data; 
end; 
/

select * from TABLE (cast(f1() as myTable)); 

---------- ---------- 
1 Row #1 
2 Row #2 
3 Row #3 
4 Row #4 
5 Row #5 

從上在該線程上發帖:

您已經知道的方式是唯一使用的方式 選擇語句中的REF CURSOR。

+0

這個不太明白嗎? '你已經知道的方法是在select語句中使用REF CURSOR的唯一方法。' – user75ponic

+1

如果你閱讀鏈接中的整個線程,它是有意義的;)基本上,'從雙重'選擇get_employee_details('7369'),是你獲得SQL的一切。 'ref cursors'並不是真的被這樣使用,它們是用於在子程序之間傳遞的(我認爲在某些情況下用於客戶端庫,但不要在此引用我)。 – 2012-12-03 19:33:56

+0

啊,我看到:-)因此,使用sql語句引用遊標只有有限的選擇,除非在plsql塊中使用。謝謝 – user75ponic

6

爲此,您可能需要查看PIPELINED函數。不過你必須在PL/SQL級別聲明顯式類型。這部分將設置輸出列名:

CREATE OR REPLACE TYPE my_rec AS OBJECT (
    c CHAR, 
    n NUMBER(1) 
); 

CREATE OR REPLACE TYPE my_tbl AS TABLE OF my_rec; 

現在,最大的優點是,你不僅可以「重命名」你的專欄,但修改從光標記錄上飛了。對於前:

CREATE OR REPLACE FUNCTION my_fct 
RETURN my_tbl PIPELINED 
AS 
    -- dummy data - use your own cursor here 
    CURSOR data IS 
     SELECT 'a' as A, 1 AS B FROM DUAL UNION 
     SELECT 'b', 2 FROM DUAL UNION 
     SELECT 'c', 3 FROM DUAL UNION 
     SELECT 'd', 4 FROM DUAL; 
BEGIN 
    FOR the_row IN data 
    LOOP 
     PIPE ROW(my_rec(the_row.a, the_row.b*2)); 
     --         ^^ 
     --       Change data on the fly 
    END LOOP; 
END 

用法:

SELECT * FROM TABLE(my_fct()) 
--   ^^^^^^^^^^^^^^^ 
--  Use this "virtual" table like any 
--  other table. Supporting `WHERE` clause 
--  or any other SELECT clause you want 

生產:

C N 
a 2 
b 4 
c 6 
d 8 
+0

感謝您的解決方案。 – user75ponic

+0

@Polppan:D我甚至不希望你會在這麼長時間後看看!我很高興你能欣賞它。 –

相關問題