Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何对照Oracle中的动态列表检查IN条件?_Oracle_List_Plsql_Cursor - Fatal编程技术网

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

如何对照Oracle中的动态列表检查IN条件?,oracle,list,plsql,cursor,Oracle,List,Plsql,Cursor,编辑:更改标题以符合下面的代码 我试图从Oracle表中检索一个可接受值的列表,然后对另一个执行选择,同时将一些字段与所述列表进行比较 我试图用游标(如下所示)实现这一点,但失败了 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_GENE

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

我试图从Oracle表中检索一个可接受值的列表,然后对另一个执行选择,同时将一些字段与所述列表进行比较

我试图用游标(如下所示)实现这一点,但失败了

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中如何执行此操作?

为什么要拉列表而不是使用半联接

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

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

create type list_record is table of varchar2(128)
/
这是因为我们不能在SQL语句中使用PL/SQL类型。唉,这意味着我们不能使用
%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条款中的内容。”

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

“我想有一个 使用 这是在直接半连接上的“

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


在11g企业版中,我们可以选择使用。这是一个更好的解决方案,但并不适用于所有表

因为主SELECT语句可能会重复执行。我认为,如果迭代次数太多,任何嵌套选择都会效率低下,因此我尝试缓存我的列表。这听起来不是讽刺,但听起来好像你认为你有性能优化问题,而不是你知道你有一个问题。我建议将我提供的与APC的解决方案进行基准测试,看看是否有显著差异。事实上,我知道我有一个优化问题。我现在正忙于重构其他人的代码,因为像我上面伪键入的代码那样由块组成的SP正在破坏我们的大数据集。:)说实话,为了满足我的好奇心,我真的很有兴趣对你们的两种解决方案进行基准测试,但我更愿意尝试一些新的东西来最终解决这个问题d如果提供的嵌套子查询不引用主查询中的任何内容,Oracle应确定该子查询可以执行一次,然后重新使用结果集。这应该与将C_列表作为变量/对象集合类型相同。我们都知道,乐观主义者往往会决定做最糟糕的事情。提示可能会有所帮助,或者强制执行不同的执行计划。谢谢。我明白您的意思,但是我看到您仍然需要执行SELECT语句来填充IN子句的列表。我认为与直接半连接相比,使用此连接可以显著提高性能(如下面Adam Musch提供的)?:)令人烦恼的是,如果您的最终操作是更新或删除,那么您的代码将工作得非常好-只有选择不接受批量绑定作为输入。顺便说一句,您有资源泄漏-没有关闭引用游标。为什么不是好的本地游标?