【问题标题】:using Oracle SQL - regexp_substr to split a record使用 Oracle SQL - regexp_substr 拆分记录
【发布时间】:2015-04-30 05:03:59
【问题描述】:

我需要拆分可能包含','';' 的列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)        

【问题讨论】:

  • 错误是:Ora-00920:无效的关系运算符
  • 这里的冒号是干什么用的? " = :CMD。"
  • 如果您想要的元素位于 NULL 元素之后,则 '[^,|;]+' 形式的正则表达式将返回错误的元素。有关更多信息,请参阅此其他帖子:stackoverflow.com/questions/30192688/…

标签: sql oracle regexp-substr


【解决方案1】:

错误 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))

【讨论】:

  • 谢谢,问题是缺少 'IS NOT NULL' 。
【解决方案2】:

这是一个常见问题,我会放入一个函数中,然后根据需要调用它:

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 以对令牌进行去重(如上面重复的“测试”令牌)

【讨论】:

    猜你喜欢
    • 2017-10-08
    • 2021-07-14
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    相关资源
    最近更新 更多