在Oracle中删除多个尾随空格并在列中更新

在Oracle中删除多个尾随空格并在列中更新,oracle,Oracle,我有一个包含M*N行和列的oracle表,它有多个尾随空格 我使用下面两条语句来查找尾随空格并更新值。我正在寻找一个可以在一个表上工作的脚本,不知道该表有多少列,这些列的名称,其中哪些是varchar数据类型,等等 Select * From Table Where Column_Name<> TRIM(Column_Name); UPDATE Table set Column_Name= trim(Column_Name) where Condition=; commit;

我有一个包含M*N行和列的oracle表,它有多个尾随空格

我使用下面两条语句来查找尾随空格并更新值。我正在寻找一个可以在一个表上工作的脚本,不知道该表有多少列,这些列的名称,其中哪些是varchar数据类型,等等

Select * From Table Where Column_Name<> TRIM(Column_Name);

UPDATE Table 
set Column_Name= trim(Column_Name)
where Condition=;
commit;

下面是我能想到的最简单的例子。 如果您对dbms_output.put_行生成的输出感到满意,请将其替换为execute immediate。如果在您的案例中有意义,请取消对提交的注释

BEGIN
   FOR col_i IN (SELECT OWNER, table_name, column_name FROM all_tab_columns WHERE OWNER = 'XXX' AND table_name = 'YYY' AND (data_type LIKE '%CHAR%' OR data_type LIKE '%CLOB') )
   LOOP
      dbms_output.put_line('UPDATE ' || col_i.OWNER || '.' || col_i.table_name ||' set ' || col_i.column_name || ' = LTRIM(' || col_i.column_name || ') WHERE ' || col_i.column_name || ' LIKE '' %''');
--    commit;
   END LOOP;
end; 

这里有一个解决你问题的方法。如果您要多次使用该程序,则必须对其进行操作。特别是我不处理错误,我只查找VARCHAR2列

设置:

create table tbl ( id number, name varchar2(10), notes varchar2(30) );

insert into tbl values ( 1, 'Joe  ', 'No notes' );
insert into tbl values ( 2, 'Ann'  , 'Spaces  ' );
insert into tbl values ( 3, 'Ben'  , null       );
commit;

select id, '*|'||name||'|*' as name, '*|'||notes||'|*' as notes
from   tbl
;

ID NAME           NOTES                            
-- -------------- ----------------------------------
 1 *|Joe  |*      *|No notes|*                      
 2 *|Ann|*        *|Spaces  |*                      
 3 *|Ben|*        *||*              
请注意第一行的名称和第二行的注释-它们后面有空格。我添加了前导
*
和尾随
*
来显示尾随空格的位置

更新此表的正确方法是

update tbl
  set name = rtrim(name), notes = rtrim(notes)
  where name like '% ' or notes like '% '
;
-请注意WHERE子句,以确保我们不会使用尾随空格更新没有任何值的行。(更新行本身似乎无害,但会增加大量开销,以及它们生成的所有撤消和重做操作。)

那么,下面是PL/SQL代码,它动态生成这个
UPDATE
语句:

create or replace procedure trim_trailing_spaces (
  tbl_name in varchar2,
  own      in varchar2 default null
)
as
  sql_text varchar2(4000)
    := 'update ' || nvl(own, user) || '.' || tbl_name;
  set_text varchar2(1000)
    := chr(10) || '  set   ';
  where_text varchar2(1000)
    := chr(10) || '  where ';
begin
  for r in ( select column_name as col
             from   all_tab_columns
             where  owner       = nvl(upper(own), user)
               and  table_name  = upper(tbl_name)
               and  data_type = 'VARCHAR2'
           )
  loop
    set_text := set_text || r.col || ' = rtrim( ' || r.col || '), ';
    where_text := where_text || r.col || ' like ''% '' or ';
  end loop;

  sql_text := sql_text || rtrim(set_text, ', ') || rtrim(where_text, 'or ');
  execute immediate sql_text;
  commit;
end trim_trailing_spaces;
/
编译它,然后执行它。我传入了表名
'tbl'
(我们之前创建的表),并且我没有给出可选的第二个参数(对于与我自己不同的架构名称),因此更新后的表将是我架构中的表。然后从上面执行
SELECT
语句以查看更改

exec trim_trailing_spaces('tbl')

select id, '*|'||name||'|*' as name, '*|'||notes||'|*' as notes
from   tbl
;

ID NAME           NOTES                            
-- -------------- ----------------------------------
 1 *|Joe|*        *|No notes|*                      
 2 *|Ann|*        *|Spaces|*                      
 3 *|Ben|*        *||*   

所以,它似乎起了作用

问题还不清楚。您是否正在寻找一个可以在表上工作的脚本,但不知道该表有多少列,这些列的名称,以及其中哪些是一种或另一种字符串数据类型(与日期或数字相反),等等。?也就是说,您正在寻找动态SQL吗?或者您知道列名吗?您只是在寻找一条SQL语句,以便在一次遍历表的过程中完成这项工作?另外:TRIM将删除前导空格和尾随空格;可以吗?您说过只想删除尾随空格。查看所有的选项卡列这看起来不错,但OP特别想一次更新整个表。在您的方法中,您分别更新每个列—可能是性能问题。还要注意,要修剪尾随空格,应该使用RTRIM,但这是一个小问题。
exec trim_trailing_spaces('tbl')

select id, '*|'||name||'|*' as name, '*|'||notes||'|*' as notes
from   tbl
;

ID NAME           NOTES                            
-- -------------- ----------------------------------
 1 *|Joe|*        *|No notes|*                      
 2 *|Ann|*        *|Spaces|*                      
 3 *|Ben|*        *||*