【问题标题】:Oracle 11g split the string and it will use in Update statementOracle 11g 拆分字符串并将在 Update 语句中使用
【发布时间】:2017-10-20 08:27:50
【问题描述】:

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

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

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

  • 查找第一次出现的左括号 – “(”
    如果找到 查找下一个右括号 – “)”
    将制造商名称的最后一个字符替换为保持架代码字符
  • 如果没有找到
    将制造商名称截断为 30 个字符

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

更新语句应该是

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

请帮忙

【问题讨论】:

  • “笼子代码字符”是否总是 30 个或更少?如果没有,有什么要求?

标签: regex oracle11g substring regexp-substr


【解决方案1】:

示例中的正则表达式将笼码的前 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

【讨论】:

    【解决方案2】:

    设置

    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 语句来解决。一些准备工作在子查询中完成,其余的在MERGE 语句的UPDATE 子句中完成。

    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 个字符长怎么办?我没有尝试在我的解决方案中处理这种情况,因为我不知道所需的输出是什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多