0

同じテーブル内の他のレコードへの主キーのリストを保存したいと考えています。次に、次のような選択を実行できるようにしたいと考えています。

SELECT * FROM mytable WHERE myarraycol CONTAINS '123'

Oracle には配列データ型があることがわかりました。ただし、EXISTS 関数は、要素が指定されたインデックスに存在するかどうかのみを検証するようです。特定の変数が単一の SQL クエリで配列データ型の列にあることを確認する方法はありますか?

配列データ型を使用する代わりに、「123,324,543,23432」のようなコンマ区切りの文字列として PK を格納してみました。私のクエリは次のようになりました。

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

PK '123' を含むすべてのレコードが必要な場合。これに関する問題 (とりわけ) は、別のレコードの値が「432,9912399,432」の場合、「9912399」の「123」が原因でこのレコードが表示されることです。

「LIKE」と文字列を使用してこの問題を解決できる1つの方法は、where句を次のようにすることです。

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

「123」が文字列全体の中央、最初、または最後にあるかどうかをテストしますが、それは見苦しくなり始めます。

誰かが以前にこのようなことをしたことがあり、正しい方向に向けることができますか?

4

1 に答える 1

2

In theory Oracle has MEMBER OF function for collection but regarding 3rd normal form you idea looks strange.

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  /

An example for function to get the plsql table from comma-separated stuff:

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;
于 2012-10-19T20:19:53.500 に答える