Oracle中如何删除多个空格

发布于 2024-09-26 18:39:43 字数 1083 浏览 5 评论 0原文

我有一个 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.

I have an Oracle table which contains data like 'Shiv------Shukla' (consider '-' as space).
Now I need to write a program which leaves just one space and removes all other spaces.

Here is the program which I've made but it is not giving me expected result.

 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;
/

My table is

SQL> select * from asset_y;

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

after running the procedure i m getting the following output.

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

PL/SQL procedure successfully completed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

想你的星星会说话 2024-10-03 18:39:43

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

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

可以找到有关 owa_pattern 包的更多信息 此处

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

Since regexp_replace is not available in Oracle 9i maybe you can use owa_pattern routines for simple regex replaces:

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

More info about owa_pattern package can be found here

Bear in mind, that "\s" will match tabs and newlines as well.

神回复 2024-10-03 18:39:43

使用 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 asset_y
SET name = replace_multi_spaces( name );

顺便说一句:使用 Oracle 10,您可以使用 REGEXP_REPLACE

With Oracle 9 you could write your own function:

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;

and call it in a single update-statement:

UPDATE asset_y
SET name = replace_multi_spaces( name );

BTW: With Oracle 10 you could use REGEXP_REPLACE.

携君以终年 2024-10-03 18:39:43

您的问题是这部分:

   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;
/

Your problem is this part:

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

However many times you do that within the inner loop it starts with the same value of REC.NAME as before. Changing it to this would fix it:

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

However, it is a pretty inefficient way to do this job if the table is large. You could instead do this:

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

      EXIT WHEN SQL%ROWCOUNT = 0;
   END LOOP;
END;
/
情愿 2024-10-03 18:39:43

另一种方式:

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;

Another way:

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;
戏舞 2024-10-03 18:39:43

确认循环!不需要循环这

将在 T-SQL 中工作...不幸的是我没有 pl/sql 环境来编写它。PL/SQL 将等效于这里使用的所有内容(我认为 substr 代替 substring 和 | 代替 + )

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...

Ack loops! No need to loop this

This will work in T-SQL...unfortunately I have no pl/sql environment to write this in. PL/SQL will have equivlents to everything used here (I think substr instead of substring and | instead of +)

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

You'll have to retool it to work for oracle and you'll need to replace any reference to @name to 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)))

Sorry if it won't run as is, as I mentioned I lack an oracle install here to confirm...

Just to add...I normally turn that query above into a function named formatname and call it as select formatname(array_y.name) from... This allows me to include some form of error handling. The query will fail if patindex('% %',array_v.name) returns a null...meaning there is no space. You could do the same in a select statement using cases I guess:

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...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文