Oracle数组“包含”函数

时间:2012-10-19 19:47:12

标签: sql arrays oracle

我想将主键列表存储到同一个表中的其他记录中。然后我希望能够执行类似于以下内容的选择:

SELECT * FROM mytable WHERE myarraycol CONTAINS '123'

我已经看到Oracle有一个array data type。但是,看起来EXISTS函数只验证元素是否存在于指定的索引处。有没有办法在单个SQL查询中验证给定变量是否在数组数据类型列中?

作为使用数组数据类型的替代方法,我尝试将PK存储为逗号分隔的字符串,如“123,324,543,23432”。我的查询看起来像:

SELECT * FROM mytable WHERE mystringcol LIKE '%123%'

如果我想要所有带有PK'123'的记录。这个(以及许多其他记录)的问题是,如果另一个记录的值为“432,9912399,432”,则该记录将显示为“9912399”中的“123”。

使用“LIKE”和字符串解决此问题的一种方法可能是使用where子句:

WHERE mystringcol LIKE '%,123,% OR mystringcol LIKE '%123, OR mystringcol LIKE '%,123

测试“123”在整个字符串的中间,开头或结尾,但是开始变得难看,我宁愿不这样做。

有没有人之前做过这样的事情并且可以指出我正确的方向?

1 个答案:

答案 0 :(得分:2)

理论上,Oracle具有收集功能的成员,但对于第三种常规形式,你的想法看起来很奇怪。

SQL> CREATE OR REPLACE PROCEDURE member_of_example AS
  2    TYPE nestedTableType IS TABLE OF VARCHAR2(10);
  3    myTable1 nestedTableType;
  4    result BOOLEAN;
  5  BEGIN
  6    myTable1 := nestedTableType('F', 'G', 'S');
  7    result := 'George' MEMBER OF myTable1;
  8    IF result THEN
  9      DBMS_OUTPUT.PUT_LINE('''George'' is a member');
 10    END IF;
 11  END member_of_example;
 12  /

从逗号分隔的东西中获取plsql表的函数示例:

CREATE OR REPLACE function Str2NmbTbl(p_str varchar2) return number_table is
l_col number_table := number_table();
l_pos number;
l_cnt number := 1;
l_num number;
begin     
    l_pos := instr(p_str, '[', l_cnt);
    while l_pos > 0 loop       
        l_num := to_number(substr(p_str, l_pos + 1, instr(p_str, ']', 1, l_cnt) - l_pos - 1));
        l_col.extend;

        l_col(l_cnt) := l_num;
        l_cnt := l_cnt + 1;
        l_pos := instr(p_str, '[', l_pos + 1);
    end loop;  

    return l_col;
end;
/

with s as
(select 1 id, '[11412][21][3131][3333]'    str from dual union all
 select 2 id, '[64376][553]'               str from dual union all
 select 3 id, '[5943][74621][19][3333][0]' str from dual union all
 select 4 id, '[21593][22321][43][094]'    str from dual --union all
)
select id, Str2NmbTbl(str) collctn
from s;