Ric*_*gan 2 oracle plsql list cursor
编辑:更改标题以适合下面的代码。
我试图从 Oracle 表中检索可接受值的列表,然后对另一个表执行 SELECT,同时将某些字段与所述列表进行比较。
我试图用光标来做到这一点(如下所示),但是失败了。
DECLARE
    TYPE gcur IS REF CURSOR;
    TYPE list_record IS TABLE OF my_table.my_field%TYPE;
    c_GENERIC gcur;
    c_LIST list_record;
BEGIN
    OPEN c_GENERIC FOR
    SELECT my_field FROM my_table
    WHERE some_field = some_value;
    FETCH c_GENERIC BULK COLLECT INTO c_LIST;
    -- try to check against list
    SELECT * FROM some_other_table
    WHERE some_critical_field IN c_LIST;
END
基本上,我想做的是将可接受的值列表缓存到变量中,因为稍后我将反复检查它。
在 Oracle 中如何执行此操作?
我们可以使用集合来存储值以满足您的目的,但它们需要声明为 SQL 类型:
create type list_record is table of varchar2(128)
/
这是因为我们不能在 SQL 语句中使用 PL/SQL 类型。唉,这意味着我们不能使用%TYPEor %ROWTYPE,因为它们是 PL/SQL 关键字。
您的程序将如下所示:
DECLARE
    c_LIST list_record;
BEGIN
    SELECT my_field 
    BULK COLLECT INTO c_LIST 
    FROM my_table
    WHERE some_field = some_value;
    -- try to check against list
    SELECT * FROM some_other_table
    WHERE some_critical_field IN ( select * from table (c_LIST);
END;    
“我发现您仍然必须执行 SELECT 语句来填充 IN 子句的列表。”
如果值在表中,则没有其他方法可以将它们放入变量中:)
“我认为使用它比直接半连接有显着的性能提升”
不必要。如果您只使用这些值一次,那么子查询肯定是更好的方法。但是,当您希望在多个离散查询中使用相同的值时,填充集合是更有效的方法。
在 11g 企业版中,我们可以选择使用结果集缓存。这是一种更好的解决方案,但并不适合所有表。