2015-08-14 72 views
2

我對Oracle非常陌生,並被要求編寫一個過程來查詢表中的某些數據。我用2個參數構建它,一個遊標和一個數字。基本上我有:是否需要在程序中查詢遊標?

PROCEDURE PROC_NAME (
    cursor_name  IN OUT NOCOPY MY_DEFINED_CURSOR_TYPE, 
    a_number  IN NUMBER); 
AS 
BEGIN 

OPEN CURSOR_NAME FOR 
    SELECT 
     column 
    FROM 
     table 
    WHERE 
     table.dat_value > (SYSDATE - a_number); 
END PROC_NAME; 

它的工作原理就像一個魅力,我可以從光標中獲取列。我的問題是請求者不想傳入光標,他們只是想傳入數字。我從來沒有創建過一個不使用遊標來返回查詢值的過程,我見過的例子只有這樣才能做到。這可能嗎?

+0

這聽起來像你只是被要求到'cursor_name'參數從'IN OUT'改爲'OUT'。作爲一種風格,我會在'IN'參數之後加入'OUT'參數,但這只是個人偏好。 –

+0

有多種方式可以返回數據而不是遊標。請求者能指定他們想要的東西嗎?嵌套表,關聯數組,單個標量值...? –

+1

請求者是否被用於SQL Server?在SQL Server中,遊標的返回是隱含的,不需要通過參數。 –

回答

1

你可以使用一個集合:

CREATE PROCEDURE PROC_NAME (
    a_number IN NUMBER, 
    numbers OUT SYS.ODCINUMBERLIST 
) 
AS 
BEGIN 
    SELECT number_value 
    BULK COLLECT INTO numbers 
    FROM table_name 
    WHERE date_value > (SYSDATE - a_number); 
END PROC_NAME; 

另外,如果你不想在光標通過那麼你可以只通過一個出來:

CREATE OR REPLACE PROCEDURE PROC_NAME (
    a_number IN NUMBER, 
    numbers OUT SYS_REFCURSOR 
) 
AS 
BEGIN 
    OPEN numbers FOR 
    SELECT number_value 
    FROM table_name 
    WHERE date_value > (SYSDATE - a_number); 
END PROC_NAME; 
1

使用a function呢?但與程序輸出參數相比,這只是「風格」差異。無論如何,必須隱式傳遞返回的值(不同於在@ShannonSeverance中提到的SQL Server)。

function f(
    p_days in number 
) return my_defined_cursor_type is 
    v_cur my_defined_cursor_type; 
begin 
    open v_cur for 
    select 
     column 
    from 
     table 
    where 
     table.dat_value > (sysdate - p_days); 

    return v_cur; 
end; 
/

使用

declare 
    v_cur my_defined_cursor_type := f(42); 
begin 
    -- use v_cur as you like 
end; 
1

如果要應用一些PL/SQL邏輯,但仍使用select查詢的數據(即不通在遊標 - 使用pipelined functions

您需要定義結果行和表的類型; FETCH遊標和PIPE結果在函數中。

CREATE or replace type MY_DEFINED_ROW_TYPE as object 
(
txt    VARCHAR2(30) 
); 
/

create or replace type MY_DEFINED_TABLE_TYPE as table of MY_DEFINED_ROW_TYPE 
/


create or replace function FUN_NAME(a_number IN NUMBER) return 
MY_DEFINED_TABLE_TYPE 
PIPELINED 
as 
    cur MY_DEFINED_CURSOR_TYPE; 
    v_txt varchar2(30); 
begin 
    OPEN cur 
     FOR 
     SELECT 
     column 
     FROM table 
     WHERE table.dat_value > (SYSDATE - a_number); 
    LOOP 
    FETCH cur INTO v_txt; 
    EXIT WHEN cur%NOTFOUND; 
    pipe row(v_txt); 
    END LOOP;  
    return; 
end; 
/

用法:

select * from table (FUN_NAME(2));