-1

我不知道如何在 Oracle 11g 中拆分字符串。

我的输入输入字符串是制造商名称。

如果制造商名称超过 30 个字符

  • 查找第一次出现的左括号 – “(”<br> 如果找到 查找下一个出现的右括号 – “)”<br> 将制造商名称的最后一个字符替换为笼代码字符
  • 如果未找到
    ,将制造商名称截断为 30 个字符

示例:
输入:
Arrow Industries International-MX7(4432)
输出:
Arrow Industries Interna(4432)

更新语句应该是

update manufacture_table 
  set name='Arrow Industries Interna(4432)'

请帮忙

4

2 回答 2

0

设置

create table manufacture_table(name varchar2(80));

insert into manufacture_table values ('International Business Machines Corp.');
insert into manufacture_table values ('Arrow Industries International-MX7(4432)');
insert into manufacture_table values ('Extra Company');
insert into manufacture_table values ('My Business (33042)');
insert into manufacture_table values 
          ('Very long name for a company, really very long (0123456789012345678901234)');
insert into manufacture_table values
          ('Company name-(01234567890123456789012345678901234567)');

commit;
select name, length(name) as len from manufacture_table;

NAME                                                                                  LEN
-------------------------------------------------------------------------------- --------
International Business Machines Corp.                                                  37
Arrow Industries International-MX7(4432)                                               40
Extra Company                                                                          13
My Business (33042)                                                                    19
Very long name for a company, really very long (0123456789012345678901234)             74
Company name-(01234567890123456789012345678901234567)                                  53

 6 rows selected

这类问题通常最好用一个MERGE语句来解决。一些准备工作在子查询中完成,其余在语句的UPDATE子句中完成MERGE

merge into manufacture_table t
  using (
         select rowid                          as rn,
                regexp_substr(name, '[^(]*')   as init_str,
                regexp_substr(name, '\(.*?\)') as cage
         from   manufacture_table
        ) q
        on (q.rn = t.rowid)
when matched then update
    set t.name = case when q.cage is null       then substr(q.init_str, 1, 30)
                      when length(q.cage) >= 30 then substr(q.cage, 1, 30)
                      else substr(q.init_str, 1, 30 - length(q.cage)) || q.cage   end
where length(t.name) > 30
;

4 rows merged.

select name, length(name) as len from manufacture_table;

NAME                              LEN
------------------------------   ----
International Business Machine     30
Arrow Industries Interna(4432)     30
Extra Company                      13
My Business (33042)                19
Ver(0123456789012345678901234)     30
(01234567890123456789012345678     30

我在样本数据中包含了几个“例外情况”,以了解它们是如何处理的。然而,还有很多其他的,您的要求需要指定在每种情况下应该发生什么(或者它需要指定它们是不可能的)。例如,如果一个公司名称的名称中有一对括号,从位置 13 到 20,然后名称继续超过右括号,但总名称有 40 个字符长怎么办?我没有尝试在我的解决方案中处理此类情况,因为我不知道所需的输出是什么。

于 2017-05-20T18:26:11.980 回答
0

示例中的正则表达式将笼子代码的前 24 个字符和 6 个字符放入捕获组 1 和 2。

因此,通过将其替换为\1\2您可以松开两者之间的字符。

子字符串确保结果不会超过 30,即使没有进行替换。

并且感谢 CASE,如果它不超过 30,那么 output=input。

 select input,
(case 
 when length(input) > 30 then substr(REGEXP_REPLACE(input, '^(.{24}).*(\(\w{4}\))', '\1\2'),1,30)
 else input
 end) as output
from (
    select 'Arrow Industries International-MX7(4432)' as input from dual
    union all
    select 'Wooden BowIndustries International-WBC' from dual
) q

如果笼码的长度是可变的,那么它就变得有点复杂了。由于我们需要计算要添加到笼子代码中的子字符串的长度:

select input,
(case 
 when length(input) > 30 
 then substr(input,1,30-coalesce(length(REGEXP_SUBSTR(input,'\(\w{1,28}\)')),0)) || REGEXP_SUBSTR(input,'\(\w{1,28}\)')
 else input
 end) as output
from (
    select 'Arrow Industries International-MX7(1234567)' as input from dual
    union all
    select 'Bow Industries International-BII(a12)' from dual
) q

要在更新中使用它:

update manufacture_table 
set name=substr(name,1,30-coalesce(length(REGEXP_SUBSTR(name,'\(\w{1,28}\)')),0)) || REGEXP_SUBSTR(name,'\(\w{1,28}\)')
where length(name)>30
于 2017-05-20T11:29:49.473 回答