如何在Oracle中删除多个空格

时间:2010-10-12 11:06:49

标签: sql oracle plsql oracle9i

我有一个Oracle表,其中包含'Shiv------Shukla'等数据(将'-'视为空格) 现在我需要编写一个程序,只留下一个空格并删除所有其他空格。

这是我制作的程序,但它没有给我预期的结果。

 DECLARE
  MAX_LIMIT VARCHAR2(50):=NULL;
  REQ          VARCHAR2(20):=NULL;
 CURSOR C1 IS
  SELECT  *
  FROM ASSET_Y;
 BEGIN
  FOR REC IN C1
   LOOP
    MAX_LIMIT:=LENGTH(REC.NAME)-LENGTH(REPLACE(REC.NAME,'-'));
     FOR I IN 1..MAX_LIMIT
      LOOP
       UPDATE  ASSET_Y
       SET  NAME=REPLACE(REC.NAME,'--','-')
       WHERE  REC.SNO=ASSET_Y.SNO;
       COMMIT;
    SELECT ASSET_Y.NAME INTO REQ FROM ASSET_Y WHERE ASSET_Y.SNO=REC.SNO;    
       DBMS_OUTPUT.PUT_LINE(REQ);
      END LOOP;
   END LOOP;
 COMMIT;
 END;
/

我的桌子是

SQL> select * from asset_y;

       SNO NAME                 FL
---------- -------------------- --
         1 Shiv------Shukla     y
         2 Jinesh               y

运行程序后,我得到以下输出。

Shiv---Shukla
Shiv---Shukla
Shiv---Shukla
Shiv---Shukla
Shiv---Shukla
Shiv---Shukla

PL/SQL procedure successfully completed.

5 个答案:

答案 0 :(得分:4)

由于Oracle 9i中没有regexp_replace,您可以使用owa_pattern例程进行简单的正则表达式替换:

  owa_pattern.change(fStr, '\s+', ' ', 'g');

有关owa_pattern包的更多信息,请访问here

请记住,“\ s”也会匹配制表符和换行符。

答案 1 :(得分:2)

使用Oracle 9,您可以编写自己的函数:

CREATE FUNCTION remove_multi_spaces( in_value IN VARCHAR2 )
RETURN VARCHAR2
AS
  v_result VARCHAR2(32767);
BEGIN
  IF( in_value IS NOT NULL ) THEN
    FOR i IN 1 .. ( LENGTH(in_value) - 1 ) LOOP
      IF( SUBSTR( in_value, i, 2 ) <> '  ' ) THEN
        v_result := v_result || SUBSTR( in_value, i, 1 );
      END IF;
    END LOOP;
    v_result := v_result || SUBSTR( in_value, -1 );
  END IF;
  RETURN v_result;
END;

并在单个update-statement中调用它:

UPDATE asset_y
SET name = replace_multi_spaces( name );

BTW:使用Oracle 10,您可以使用REGEXP_REPLACE

答案 2 :(得分:2)

你的问题就在这一部分:

   SET  NAME=REPLACE(REC.NAME,'--','-')

无论你多次在内循环中这样做,它都会以与以前相同的REC.NAME值开始。将其改为此将解决它:

   SET  NAME=REPLACE(NAME,'--','-')

但是,如果表很大,这是一种非常低效的方法来完成这项工作。你可以这样做:

BEGIN
   LOOP
      UPDATE ASSET_Y
      SET    NAME=REPLACE(NAME,'--','-')
      WHERE  NAME LIKE '%--%';

      EXIT WHEN SQL%ROWCOUNT = 0;
   END LOOP;
END;
/

答案 3 :(得分:1)

另一种方式:

CREATE OR REPLACE
FUNCTION remove_multi_spaces( in_value IN VARCHAR2 )
RETURN VARCHAR2 IS
  v_result VARCHAR2(32767) := in_value;
BEGIN
  LOOP
    EXIT WHEN INSTR(v_result,'  ') = 0;
    v_result := REPLACE(v_result, '  ', ' ');
  END LOOP;
  RETURN v_result;
END remove_multi_spaces;

答案 4 :(得分:1)

Ack循环!无需循环此

这将在T-SQL中工作...遗憾的是我没有pl / sql环境来编写它.PL / SQL将与这里使用的所有内容相同(我认为substr而不是substring和|而不是+)< / p>

declare @name varchar(200)
set @name = 'firstword          secondword'
select left(@name,(patindex('% %',@name)-1)) + ' '  + ltrim(substring(@name,(patindex('% %',@name)+1),len(@name)))

你必须重新调整它才能为oracle工作,你需要将对@name的任何引用替换为asset_y.name

    select left(asset_y.name,(patindex('% %',asset_y.name)-1)) || ' ' || ltrim(substring(asset_y.name,(patindex('% %',asset_y.name)+1),len(asset_y.name)))

很抱歉,如果它不能按原样运行,正如我所提到的,我在这里缺少oracle安装来确认......

只是添加...我通常将上面的查询转换为名为formatname的函数,并将其称为select formatname(array_y.name)from ...这允许我包含某种形式的错误处理。如果patindex('%%',array_v.name)返回null,则查询将失败...意味着没有空格。您可以使用我猜测的情况在select语句中执行相同的操作:

select case when patindex('% %',array_v.name) > 0 then 
left(asset_y.name,(patindex('% %',asset_y.name)-1)) || ' ' || ltrim(substring(asset_y.name,(patindex('% %',asset_y.name)+1),len(asset_y.name)))
else asset_y.name
from...