正規表現を使用して、単一の SQL ステートメントでデータを解析できます。次に、任意のフィルターを適用して、事前定義されたリストにない値のセットを見つけることができます
SQL> ed
Wrote file afiedt.buf
1 with test as
2 (select 'ABC~DEF~GHI~JKL~MNO' str from dual)
3 select regexp_substr (str, '[^~]+', 1, rownum) split
4 from test
5* connect by level <= length (regexp_replace (str, '[^~]+')) + 1
SQL> /
SPLIT
----------------------------------------------------------------------------
ABC
DEF
GHI
JKL
MNO
このようなこともできます
SQL> ed
Wrote file afiedt.buf
1 with test as
2 (select 1 id, 'ABC~DEF~GHI~JKL~MNO' str from dual union all
3 select 2, 'XY~PDQ~435' from dual union all
4 select 3, 'This~is~a~test' from dual)
5 select id, regexp_substr (str, '[^~]+', 1, e.lvl) split
6 from test,
7 (select level lvl
8 from dual
9 connect by level <= (select max(regexp_count(str,'~')) + 1
10 from test)) e
11* where regexp_substr (str, '[^~]+', 1, e.lvl) is not null
SQL> /
ID SPLIT
---------- --------------------
1 ABC
2 XY
3 This
1 DEF
2 PDQ
3 is
1 GHI
2 435
3 a
1 JKL
3 test
1 MNO
12 rows selected.
もちろん、これは特に効率的ではありません。さまざまな部分文字列に効果的にインデックスを付けることができないため、テーブルを完全にスキャンする必要があります。行を生成する方法は他にもあります。Rob van Wijk のブログで、さまざまな間隔ベースの行生成手法のパフォーマンスを比較した記事があります。
通常、データ モデルを修正する方がはるかに優れています。区切りデータを列に格納することは、基本的な正規化の原則に違反します。データを別の列 (おそらく、既存のテーブルと 1 対多の関係にある別のテーブル) に格納した場合、データにインデックスを付けて、事前定義された有効なリストにマップする外部キー制約を作成できます。これにより、無効なデータが最初から挿入されるのを防ぐことができます (または、少なくとも将来的に新しい無効な行が追加されるのを防ぐことができます)。