在Oracle中删除多个尾随空格并在列中更新
我有一个包含M*N行和列的oracle表,它有多个尾随空格 我使用下面两条语句来查找尾随空格并更新值。我正在寻找一个可以在一个表上工作的脚本,不知道该表有多少列,这些列的名称,其中哪些是varchar数据类型,等等在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;
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|* *||*