【问题标题】:remove extra + from text SQL从文本 SQL 中删除多余的 +
【发布时间】:2017-06-05 19:43:27
【问题描述】:

这是指其他人之前提出的问题 previous question

我的问题是我如何调整这个解决方案,以便在运行任何函数/脚本之前,名称和值字段被剥离任何额外的 + 并更新,因此没有额外的 + 保留。

例如

Name     Value
A+B+C+   1+2+3+
A++B     1++2

这应该更新为

   Name     Value
    A+B+C   1+2+3
    A+B     1+2

更新完成后,我可以运行上一个问题中提供的解决方案。

谢谢

【问题讨论】:

  • replace(columnname, '++', '+')
  • 这不会删除最后一个 +
  • 在选择时您可以使用这样的查询 - SELECT RIGHT('HELLO WORLD', LEN('HELLO WORLD+') - 1)

标签: sql oracle oracle11g


【解决方案1】:

您需要将++ 替换为+ 并删除字符串末尾的+

/* sample data */
with input(Name, Value) as (
                            select 'A+B+C+'   ,'1+2+3+' from dual union all
                            select 'A++B'     ,'1++2'   from dual
                            )
/* query */
select trim('+' from regexp_replace(name,  '\+{2,}', '+') ) as name,
       trim('+' from regexp_replace(value, '\+{2,}', '+') ) as value
from input     

如果你需要更新一个表,你可能需要:

update yourTable
set name = trim('+' from regexp_replace(name, '\+{2,}', '+') ),
    value= trim('+' from regexp_replace(value, '\+{2,}', '+') )

以更紧凑的方式,没有外部装饰(假设您没有前导+):

/* sample data */
with input(Name, Value) as (
                            select 'A+B+C+'      ,'1+2+3+' from dual union all
                            select 'A++B+++C+'   ,'1++2+++3+' from dual union all
                            select 'A+B'         ,'1+2'   from dual
                            )
/* query */
select regexp_replace(name,  '(\+)+(\+|$)', '\2') as name,
       regexp_replace(value, '(\+)+(\+|$)', '\2') as value
from input    

【讨论】:

  • 如何在没有硬编码值以及 2 列的情况下执行此操作
  • 硬编码是什么意思?您是否需要处理超过 2 次出现的 +?此外,对于 2 列,将函数应用于两列就足够了。
  • 如何为我的名为“名称”和“值”的列执行此操作。当我说硬代码时,我的意思是您手动输入了“A+B+C+”
  • 这只是一个例子。我进行了编辑以向您展示如何将其应用于表格。要对 2 列执行相同的操作,只需将函数应用于两列即可。
  • 啊,我知道这似乎可行.. 现在我只需要看看如何同时更新列
【解决方案2】:

您可以使用以下内容:

 Select substr('1+2+3+', 0, length('1+2+3+')-1) from dual ;
 Select replace('1++2', '++', '+') from dual;

我假设您的输出已经存在于可以使用的变量中。

编辑: 这是一个可以解决问题的函数(您可以在 select 子句中调用此函数从而解决问题):

CREATE OR REPLACE Function ReplaceChars
    ( name_in IN varchar2 )
    RETURN varchar2
IS
    changed_string varchar2(20) ;
BEGIN

    changed_string:=replace(name_in, '++', '+') ;

    CASE WHEN substr(changed_string, -1) in ('+')
        then
            changed_string:=substr(changed_string,0, length(changed_string) - 1) ;
        else changed_string:=changed_string ;
    end CASE ;

    RETURN changed_string;
END;

【讨论】:

  • 这是硬编码值,是否可以在两个列名中添加?
  • 如何为我的两列修改这个?感谢您到目前为止的帮助
  • @Laura 从 中选择 ReplaceChars(col1), ReplaceChars(col2) ;
【解决方案3】:

您可以使用以下内容:

LTRIM(RTRIM (REGEXP_REPLACE (column_name, '\+{2,}', '+'), '+'),'+')

例如:

    SELECT LTRIM(RTRIM (REGEXP_REPLACE ('+A+++B+C+++D++', '\+{2,}', '+'), '+'),'+') VALUE
  FROM DUAL;

返回输出:A+B+C+D

【讨论】:

  • 我怎样才能使用它但同时更新。?所以阅读这两列并更新这两列以反映变化
  • @Laura 是的。您需要在上述函数中同时传递 Name 和 Value 列。其输出可用于进一步处理
【解决方案4】:

如果您正在使用 ssms,请尝试一下:::

UPDATE tablename
SET colname= 
CASE colname WHEN LIKE '%++%' THEN
    WHILE colname LIKE '%++%'
        (REPLACE(colname,++,+))
    END LOOP

WHEN LIKE '%+' THEN
    SUBSTR(colname, 1, LENGTH(colname)-1)

WHEN LIKE '+%' THEN
    SUBSTR(colname, 2, LENGTH(colname))

ELSE
   colname
END

【讨论】:

  • Oracle(NOT SQL SERVER) 不支持LEFT()LEN() 函数。
  • @NicholasKrasnov,我猜“LTRIM”和“RTRIM”可以等效地用于分别替换“LEFT”和“RIGHT”功能。也可以使用“LENGTH”代替“LEN”,请参考。
  • set 语句在哪里,这是只做一列吗?我可以用 分隔它,以便它在 2 列上执行此操作吗?
  • @Laura,每次想要更新列值时都应该使用“SET”。无论是一列还是更多。
  • 此构造不适用于 oracle。我收到“SQL 命令未正确结束”的错误
猜你喜欢
  • 2014-08-07
  • 2018-04-09
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
  • 2022-12-18
  • 2017-11-06
相关资源
最近更新 更多