2015-08-14 18 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));