代码之家  ›  专栏  ›  技术社区  ›  Richard Neil Ilagan

如何对照Oracle中的动态列表检查IN条件?

  •  2
  • Richard Neil Ilagan  · 技术社区  · 14 年前

    编辑:更改标题以符合下面的代码。

    我试图从一个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中如何执行此操作?

    2 回复  |  直到 14 年前
        1
  •  4
  •   APC    14 年前

    我们可以使用集合来存储值以满足您的目的,但它们需要声明为SQL类型:

    create type list_record is table of varchar2(128)
    /
    

    %TYPE %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子句。”

    如果值在表中,则没有其他方法将它们放入变量:)

    “我在想 使用 “直接半连接上的”

    不一定。如果只使用一次值,那么子查询无疑是更好的方法。但是,如果希望在许多离散查询中使用相同的值,则填充集合是更有效的方法。

    result set caching . 这是一个更好的解决方案,但并不适用于所有表。

        2
  •  1
  •   Adam Musch    14 年前

    SELECT * 
      FROM some_other_table 
     WHERE some_critical_field IN (SELECT my_field 
                                    FROM my_table
                                   WHERE some_field = some_value);