4

COMMANDS という VARCHAR2 列を含むテーブルがあります。

この列のデータは、ラベル プリンターに送信される一連の読みにくい ZPL コードであり、ZPL の中には {TABLE.COLUMN} の形式のトークンがいくつかあります。

COMMANDS にあるすべての個別の {TABLE.COLUMN} トークンのリストが欲しいです。トークン形式に一致するように、次の正規表現を作成しました。

SELECT REGEXP_SUBSTR(COMMANDS,'\{\w+\.\w+\}') FROM MYTABLE;

正規表現は機能しますが、行ごとに最初に一致したトークンのみを返します。各行のすべての正規表現一致を返す方法はありますか?

私はOracle 11GR2を使用しています。

編集 - これは 1 つの行からのデータの小さなサンプルです。各行にはそのような行が多数あります。

^FO360,065^AEN,25,10^FD{CUSTOMERS.CUST_NAME}^FS
^FO360,095^AAN,15,12^FD{CUSTOMERS.CUST_ADDR1}^FS

したがって、それがテーブルの唯一の行である場合は、次のように返したいと思います。

{CUSTOMERS.CUST_NAME}
{CUSTOMERS.CUST_ADDR1}
4

2 に答える 2

6

これは単一の行であると言っているデータのサンプルを提供しましたが、2 つの異なる行として提示しました。したがって、この例はあなたの言葉に基づいています。

 -- Sample of data from your question + extra row for the sake of demonstration
 -- id column is added to distinguish the rows(I assume you have one)
  with t1(id, col) as( 
    select 1, '^FO360,065^AEN,25,10^FD{CUSTOMERS1.CUST_NAME}^FS^FO360,095^AAN,15,12^FD{CUSTOMERS1.CUST_ADDR1}^FS' from dual union all
    select 2, '^FO360,065^AEN,25,10^FD{CUSTOMERS2.CUST_NAME}^FS^FO360,095^AAN,15,12^FD{CUSTOMERS2.CUST_ADDR2}^FS' from dual
  ),
  cnt(c) as(
    select level
      from (select max(regexp_count(col, '{\w+.\w+}')) as o_c
              from t1
            ) z
     connect by level <= z.o_c
  )
  select t1.id, listagg(regexp_substr(t1.col, '{\w+.\w+}', 1, cnt.c)) within group(order by t1.id) res
    from t1
   cross join cnt
   group by t1.id

結果:

    ID   RES
    ---------------------------------------------------------
     1   {CUSTOMERS1.CUST_ADDR1}{CUSTOMERS1.CUST_NAME}
     2   {CUSTOMERS2.CUST_ADDR2}{CUSTOMERS2.CUST_NAME}

質問に対する@a_horse_with_no_nameのコメントによると、実際には、パターンに一致しない他のすべてのものを置き換えるだけの方がはるかに簡単です。次に例を示します。

 with t1(col) as(
    select '^FO360,065^AEN,25,10^FD{CUSTOMERS.CUST_NAME}^FS^FO360,095^AAN,15,12^FD{CUSTOMERS.CUST_ADDR1}^FS' from dual
 )
 select regexp_replace(t1.col, '({\w+.\w+})|.', '\1') res
  from t1

結果:

RES
-------------------------------------------
{CUSTOMERS.CUST_NAME}{CUSTOMERS.CUST_ADDR1} 
于 2013-01-08T20:20:41.277 に答える
3

ないと思います。一致する他のトークンを取得するには、いくつかの PL/SQL を作成する必要があります。パイプライン関数を使用することをお勧めします。

まず、タイプを作成します。

create type strings as table of varchar2(200);

次に、関数:

CREATE OR REPLACE function let_me_show
return strings PIPELINED as
   l_n number;
   l_r varchar2(200);
begin
   for r_rec in
      ( SELECT commands
        FROM MYTABLE )
   loop
      l_n := 1;
      l_r := REGEXP_SUBSTR(r_rec.COMMANDS,'\{\w+\.\w+\}', 1, l_n);
      while l_r is not null
      loop
         pipe row(l_r);
         l_n := l_n + 1;
         l_r := REGEXP_SUBSTR(r_rec.COMMANDS,'\{\w+\.\w+\}', 1, l_n);         
      end loop;       
   end loop;
end;

これで、関数を使用して結果を返すことができます。

select *
from table(let_me_show())
于 2013-01-08T19:56:16.170 に答える