Check Values in sys_refcursor

社会主义新天地 提交于 2019-12-13 06:03:45

问题


I have the following code in a function

        CREATE OR REPLACE FUNCTION my_func (
        v_dt events.raised_date%TYPE
        )
        RETURN SYS_REFCURSOR
    IS    
            p_events    SYS_REFCURSOR;

        OPEN p_events FOR
                SELECT  event_id
                  FROM  events
                 WHERE  raised_date = v_dt;
RETURN p_events;
END;

I would like to check whether 100 exists in p_events cursor or not. How can I do this inside my function.

Any help is highly appreciable.


回答1:


It is not good idea to check it inside of the function. You are missing why the cursor is returned. Instead do it outside of the function.

DECLARE
    l_rc SYS_REFCURSOR := my_func();

    TYPE events_ntt IS TABLE OF NUMBER;
    l_events  events_ntt;

    l_lookup  events_ntt := events_ntt(100);
    l_diff    events_ntt;
BEGIN
    FETCH l_rc BULK COLLECT INTO l_events;

    l_diff := l_events MULTISET INTERSECT DISTINCT l_lookup;

    IF l_diff.COUNT > 0 THEN
        DBMS_OUTPUT.PUT_LINE('100 EXISTS');
    ELSE
        DBMS_OUTPUT.PUT_LINE('100 DOES NOT EXIST');
    END IF;
END;

Using Cursor Variables (REF CURSORs)

Like a cursor, a cursor variable points to the current row in the result set of a multi-row query. A cursor variable is more flexible because it is not tied to a specific query. You can open a cursor variable for any query that returns the right set of columns.

You pass a cursor variable as a parameter to local and stored subprograms. Opening the cursor variable in one subprogram, and processing it in a different subprogram, helps to centralize data retrieval. This technique is also useful for multi-language applications, where a PL/SQL subprogram might return a result set to a subprogram written in a different language, such as Java or Visual Basic.

What Are Cursor Variables (REF CURSORs)?

Cursor variables are like pointers to result sets. You use them when you want to perform a query in one subprogram, and process the results in a different subprogram (possibly one written in a different language). A cursor variable has datatype REF CURSOR, and you might see them referred to informally as REF CURSORs.

Unlike an explicit cursor, which always refers to the same query work area, a cursor variable can refer to different work areas. You cannot use a cursor variable where a cursor is expected, or vice versa.

Source: http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/sqloperations.htm#i7106

(Oracle Database PL/SQL User's Guide and Reference)




回答2:


A ref cursor is just a pointer to query. There is nothing "in" it. So the only way to find out whether the result set identified by the ref cursor contains a specific record - or indeed any records - is to fetch the cursor and read through the records.

Bear in mind that a ref cursor is a one-shot thang. We cannot fetch the same cursor more than once. We have to close and re-open it. But that means we run the risk of the second fetched result set differing from the first (unless we change the transaction's isolation level).

So the upshot is, just code the consuming procedure to fetch and use the ref cursor, and make sure it handles both the presence and absence of interesting records.




回答3:


It can be done like this

declare
  evt EVENTS%ROWTYPE;
  found_100 boolean := false;
begin
  loop
    fetch p_events into evt;
    exit when p_events%NOTFOUND;
    if evt.event_id = 100 then
      found_100 := true;
      exit;
    end if;
  end loop;
end;

but however it's very inefficient because you're possibly fetching millions of records where you actually only need 1 fetch.



来源:https://stackoverflow.com/questions/17147176/check-values-in-sys-refcursor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!