0

我在函数中有以下代码

        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;

我想检查p_events光标中是否存在 100 。我怎样才能在我的函数中做到这一点。

任何帮助都是非常可观的。

4

3 回答 3

3

引用游标只是一个查询指针。它“里面”没有任何东西。因此,找出由 ref 游标标识的结果集是否包含特定记录(或确实包含任何记录)的唯一方法是获取游标并通读记录。

请记住,参考光标是一次性的。我们不能多次获取同一个游标。我们必须关闭并重新打开它。但这意味着我们冒着第二个获取的结果集与第一个不同的风险(除非我们更改事务的隔离级别)。

所以结果是,只需编写消费过程来获取和使用 ref 游标,并确保它处理感兴趣记录的存在和不存在。

于 2013-06-17T14:36:09.807 回答
1

在函数内部检查它不是一个好主意。您错过了返回光标的原因。而是在函数之外进行。

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;

使用游标变量(REF CURSORs)

与游标一样,游标变量指向多行查询结果集中的当前行。游标变量更灵活,因为它不绑定到特定查询。您可以为返回正确列集的任何查询打开游标变量。

您将游标变量作为参数传递给本地和存储的子程序。在一个子程序中打开游标变量,并在不同的子程序中处理它,有助于集中数据检索。这种技术对于多语言应用程序也很有用,其中 PL/SQL 子程序可能会将结果集返回给用不同语言(如 Java 或 Visual Basic)编写的子程序。

什么是光标变量(REF CURSOR)?

游标变量就像指向结果集的指针。当您想在一个子程序中执行查询并在不同的子程序(可能是用不同语言编写的子程序)中处理结果时,可以使用它们。游标变量的数据类型为 REF CURSOR,您可能会看到它们被非正式地称为 REF CURSOR。

与始终引用同一个查询工作区的显式游标不同,游标变量可以引用不同的工作区。您不能在需要游标的地方使用游标变量,反之亦然。

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

(Oracle 数据库 PL/SQL 用户指南和参考)

于 2013-06-17T16:38:57.807 回答
1

可以这样做

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;

但是它的效率非常低,因为您可能要获取数百万条记录,而实际上只需要 1 次获取。

于 2013-06-17T12:33:36.047 回答