использование Oracle SQL — regexp_substr для разделения записи

Мне нужно разделить запись для столбца CMD.NUM_MAI, который может содержать ',' или ';'. Я сделал это, но это дало мне ошибку:

  SELECT REGEXP_SUBSTR (expression.num_mai,
                      '[^;|,]+',
                      1,
                      LEVEL)
  FROM (SELECT CMD.num_cmd,
               (SELECT COMM.com
                  FROM COMM
                 WHERE COMM.cod_soc = CMD.cod_soc AND COMM.cod_com = 'URL_DSD')
                  AS cod_url,
               NVL (CONTACT.nom_cta, TIERS.nom_ct1) AS nom_cta,
               NVL (CONTACT.num_mai, TIERS.num_mai) AS num_mai,
               NVL (CONTACT.num_tel, TIERS.num_tel) AS num_tel,
               TO_CHAR (SYSDATE, 'hh24:MI') AS heur_today
          FROM CMD, TIERS, CONTACT
         WHERE     (    (CMD.cod_soc = :CMD_cod_soc)
                    AND (CMD.cod_eta = :CMD.cod_eta)
                    AND (CMD.typ_cmd = :CMD.typ_cmd)
                    AND (CMD.num_cmd = :CMD.num_cmd))
               AND (TIERS.cod_soc(+) = CMD.cod_soc)
               AND (TIERS.cod_trs(+) = CMD.cod_trs_tra)
               AND (TIERS.cod_soc = CONTACT.cod_soc(+))
               AND (TIERS.cod_trs = CONTACT.cod_trs(+))
               AND (CONTACT.lib_cta(+) = 'EDITION')) experssion
CONNECT BY REGEXP_SUBSTR (expression.num_mai,'[^;|,]+',1,LEVEL)        

person ITE    schedule 29.04.2015    source источник
comment
ошибка: Ora-00920: неверный реляционный оператор   -  person ITE    schedule 29.04.2015
comment
Для чего здесь двоеточие? = :CMD.   -  person OldProgrammer    schedule 29.04.2015
comment
Регулярное выражение формы '[^,|;]+' вернет неверный элемент, если нужный элемент находится после элемента NULL. См. этот другой пост для получения дополнительной информации: столбцы в оракуле"> stackoverflow.com/questions/30192688/   -  person Gary_W    schedule 26.05.2015


Ответы (2)


Ошибка 1:

Выражение в предложении CONNECT BY является унарным. Вы должны указать как левый, так и правый операнды.

Попробуйте что-то вроде,

CONNECT BY REGEXP_SUBSTR (expression.num_mai,'[^;|,]+',1,LEVEL) IS NOT NULL

Ошибка 2:

Ваше имя переменной связывания неверно. Пример: :CMD_cod_eta Возможно, вы так хотели!

(    (CMD.cod_soc = :CMD_cod_soc)
                    AND (CMD.cod_eta = :CMD_cod_eta)
                    AND (CMD.typ_cmd = :CMD_typ_cmd)
                    AND (CMD.num_cmd = :CMD_num_cmd))
person Maheswaran Ravisankar    schedule 29.04.2015
comment
Спасибо, это сработало, проблема заключалась в отсутствующем «IS NOT NULL». - person ITE; 30.04.2015

Это распространенный вопрос, я бы задал функцию, а затем вызвал ее по мере необходимости:

CREATE OR REPLACE function fn_split(i_string in varchar2, i_delimiter in varchar2 default ',', b_dedup_tokens in number default 0)
return sys.dbms_debug_vc2coll
as
  l_tab sys.dbms_debug_vc2coll;
begin
  select regexp_substr(i_string,'[^' || i_delimiter || ']+', 1, level)
  bulk collect into l_tab
  from dual
  connect by regexp_substr(i_string, '[^' || i_delimiter || ']+', 1, level) is not null
  order by level;

  if (b_dedup_tokens > 0) then
    return l_tab multiset union distinct l_tab;
  end if;
  return l_tab;
end;
/

Это вернет таблицу varchar2 (1000), dbms_debug_vc2coll, которая является предварительно загруженным типом, принадлежащим SYS (или вы можете создать свой собственный тип, возможно, используя 4000). В любом случае, пример его использования (с пробелом, запятой или точкой с запятой в качестве разделителей):

with test_data as (
  select 1 as id, 'A;test;test;string' as test_string from dual
  union
  select 2 as id, 'Another string' as test_string from dual
  union
  select 3 as id,'A,CSV,string' as test_string from dual
)
select d.*, column_value as token
from test_data d, table(fn_split(test_string, ' ,;', 0));

Выход:

ID  TEST_STRING TOKEN
1   A;test;test;string  A
1   A;test;test;string  test
1   A;test;test;string  test
1   A;test;test;string  string
2   Another string  Another
2   Another string  string
3   A,CSV,string    A
3   A,CSV,string    CSV
3   A,CSV,string    string

Вы можете передать 1 вместо 0 в fn_split для дедупликации токенов (например, повторяющийся «тестовый» токен выше)

person tbone    schedule 29.04.2015