Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.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 其中“从CSV列表中的任何值开始”的条件_Oracle_Csv_Plsql_Oracle10g_Stringtokenizer - Fatal编程技术网

Oracle 其中“从CSV列表中的任何值开始”的条件

Oracle 其中“从CSV列表中的任何值开始”的条件,oracle,csv,plsql,oracle10g,stringtokenizer,Oracle,Csv,Plsql,Oracle10g,Stringtokenizer,可能重复: 我在PL/SQL中有一个查询,它是为处理变量中的输入而构建的,作为一个以筛选器开头的查询: WHERE product_group LIKE strProductGroup || '%' 作为一项新功能,输入变量可以包含逗号分隔的值。所以,在我期待像艺术这样的东西之前,我现在可以看到艺术,DRM 如果可能的话,我希望避免将此查询构建为字符串并使用executeimmediate。有人能想出一种方法来编写WHERE条件,该条件相当于说以Oracle 10g中CSV列表中的任何值开头

可能重复:

我在PL/SQL中有一个查询,它是为处理变量中的输入而构建的,作为一个以筛选器开头的查询:

WHERE product_group LIKE strProductGroup || '%'
作为一项新功能,输入变量可以包含逗号分隔的值。所以,在我期待像艺术这样的东西之前,我现在可以看到艺术,DRM


如果可能的话,我希望避免将此查询构建为字符串并使用executeimmediate。有人能想出一种方法来编写WHERE条件,该条件相当于说以Oracle 10g中CSV列表中的任何值开头吗?

假设您在创建两个附加对象(集合类型和函数)时没有任何限制,您可以将列表解析为可在查询中引用的集合。汤姆·凯特在他的帖子中对此进行了很好的讨论

例如,如果使用Tom的myTableType和in_list函数

SQL> create or replace type myTableType as table 
     of varchar2 (255);
  2  /

Type created.


ops$tkyte@dev8i> create or replace 
     function in_list( p_string in varchar2 ) return myTableType
  2  as
  3      l_string        long default p_string || ',';
  4      l_data          myTableType := myTableType();
  5      n               number;
  6  begin
  7    loop
  8        exit when l_string is null;
  9        n := instr( l_string, ',' );
10         l_data.extend;
11         l_data(l_data.count) := 
                 ltrim( rtrim( substr( l_string, 1, n-1 ) ) );
12         l_string := substr( l_string, n+1 );
13    end loop;
14
15    return l_data;
16  end;
17  /
然后,您可以相对轻松地搜索相等

WHERE product_group IN (SELECT column_value 
                          FROM TABLE( in_list( strProductGroup )))
但是你想做一个更具挑战性的喜欢,因为你不能在列表中做一个喜欢。然而,你可以这样做

select *
  from emp e,
       (select '^' || column_value search_regexp
          from table( in_list( 'KIN,BOB' ))) a
 where regexp_like( e.ename, a.search_regexp )

这将在EMP表中搜索ENAME以KIN或BOB开头的任何员工。在默认的SCOTT.EMP表中,这将只返回一行,即ENAME占主导地位的行。假设您在创建两个附加对象(集合类型和函数)时没有任何限制,您可以将列表解析为一个集合,以便在查询中引用。汤姆·凯特在他的帖子中对此进行了很好的讨论

例如,如果使用Tom的myTableType和in_list函数

SQL> create or replace type myTableType as table 
     of varchar2 (255);
  2  /

Type created.


ops$tkyte@dev8i> create or replace 
     function in_list( p_string in varchar2 ) return myTableType
  2  as
  3      l_string        long default p_string || ',';
  4      l_data          myTableType := myTableType();
  5      n               number;
  6  begin
  7    loop
  8        exit when l_string is null;
  9        n := instr( l_string, ',' );
10         l_data.extend;
11         l_data(l_data.count) := 
                 ltrim( rtrim( substr( l_string, 1, n-1 ) ) );
12         l_string := substr( l_string, n+1 );
13    end loop;
14
15    return l_data;
16  end;
17  /
然后,您可以相对轻松地搜索相等

WHERE product_group IN (SELECT column_value 
                          FROM TABLE( in_list( strProductGroup )))
但是你想做一个更具挑战性的喜欢,因为你不能在列表中做一个喜欢。然而,你可以这样做

select *
  from emp e,
       (select '^' || column_value search_regexp
          from table( in_list( 'KIN,BOB' ))) a
 where regexp_like( e.ename, a.search_regexp )
这将在EMP表中搜索ENAME以KIN或BOB开头的任何员工。在默认的SCOTT.EMP表中,这将只返回一行,即ENAME为王的那一行

我找到了另一行,这给了我一个想法。在我的特定情况下,输入中的值都是3个字符,因此我可以执行以下操作:

AND SUBSTR(product_group, 0, 3) IN
    (SELECT regexp_substr(strProductGroup, '[^,]+', 1, LEVEL)
      FROM dual
      CONNECT BY LEVEL <= length(regexp_replace(strProductGroup, '[^,]+')) + 1)
我喜欢这个解决方案,因为它不需要额外的类型或函数,但仅限于我的具体情况。

我找到了另一个给我一个想法的解决方案。在我的特定情况下,输入中的值都是3个字符,因此我可以执行以下操作:

AND SUBSTR(product_group, 0, 3) IN
    (SELECT regexp_substr(strProductGroup, '[^,]+', 1, LEVEL)
      FROM dual
      CONNECT BY LEVEL <= length(regexp_replace(strProductGroup, '[^,]+')) + 1)

我喜欢此解决方案,因为它不需要额外的类型或功能,但仅限于我的具体情况。

也许您希望在strProductGroup?中使用product_group?而不是重复。另一个帖子是关于11g的,我也有关于需求的开头。也许你想在strProductGroup中使用product_group?不是重复的。另一个帖子是关于11g的,我也有关于需求的开头。添加一个管道将非常方便,不是吗?@gpeche-这不会有什么坏处。但是,假设字符串适合VARCHAR2,那么它的大小限制为32k。如果每个搜索项为3个字节,逗号为第4个字节,则表示最多有8k个搜索项。这是一个集合中元素数量相当合理的集合,无需通过管道传输结果。管道化结果不会有什么坏处,但它确实增加了一些复杂性。此外,重要的是要记住查看执行计划,因为一些Oracle版本对表类型非常困惑。有时你需要添加一个基数或具体化提示来让Oracle做正确的事情。添加一个流水线将非常方便,不是吗?@gpeche-这不会有什么坏处。但是,假设字符串适合VARCHAR2,那么它的大小限制为32k。如果每个搜索项为3个字节,逗号为第4个字节,则表示最多有8k个搜索项。这是一个集合中元素数量相当合理的集合,无需通过管道传输结果。管道化结果不会有什么坏处,但它确实增加了一些复杂性。此外,重要的是要记住查看执行计划,因为一些Oracle版本对表类型非常困惑。有时,您需要添加基数或具体化提示,以使Oracle做正确的事情。