我在函数中有以下代码
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。我怎样才能在我的功能中做到这一点。
任何帮助都非常值得赞赏。
答案 0 :(得分:3)
引用游标只是一个指向查询的指针。它没有任何“内在”。因此,找出ref cursor标识的结果集是否包含特定记录(或实际上是任何记录)的唯一方法是获取光标并读取记录。
请记住,引用光标是一次性的。我们不能多次获取相同的光标。我们必须关闭并重新打开它。但这意味着我们冒第二次获取的结果集与第一次不同的风险(除非我们更改事务的isolation level)。
所以结果是,只需编写消费程序来获取和使用引用光标,并确保它处理有趣记录的存在与否。
答案 1 :(得分: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次抓取。
答案 2 :(得分: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 CURSOR)
与游标类似,游标变量指向当前行 多行查询的结果集。游标变量更灵活 因为它没有绑定到特定的查询。你可以打开一个光标 任何返回正确列的查询的变量。
将游标变量作为参数传递给local和stored 子程序。在一个子程序中打开游标变量,和 在不同的子程序中处理它有助于集中数据 恢复。这种技术对多语言也很有用 应用程序,PL / SQL子程序可能会将结果集返回给a 用不同语言编写的子程序,例如Java或Visual 基本
什么是光标变量(REF CURSOR)?
游标变量就像指向结果集的指针。你何时使用它们 您想在一个子程序中执行查询,并处理结果 在一个不同的子程序中(可能是一个不同的子程序) 语言)。游标变量的数据类型为REF CURSOR,您可以 看到他们非正式地称为REF CURSOR。
与显式游标不同,后者始终引用相同的查询工作 区域,游标变量可以指不同的工作区域。你不能 使用光标所在的光标变量,反之亦然。
来源:http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/sqloperations.htm#i7106
(Oracle数据库PL / SQL用户指南和参考)