修剪字符串中的空格 - LTRIM RTRIM不起作用

时间:2014-02-05 18:50:01

标签: sql sql-server

我试过这段代码 -

UPDATE Table
SET Name = RTRIM(LTRIM(Name))

名称的数据类型为varchar(25)

没有删除前导空格和尾随空格。当我复制粘贴一个Name时, 我明白了 -

"big dash" "space symbol" ABC001

为什么会发生这种情况?如何修剪空间?

编辑 -

问题已经得到解答。我找到了另外一个有这个问题的表。我明白了 当我复制一行时,“ - 值”。当我在此复制粘贴值的末尾按下回车键时,我看到更多破折号。见下图 -

Weird symbols

8 个答案:

答案 0 :(得分:18)

我怀疑,名称列中的一些不可读(非ascii字符)可能不会在TRIM调用中被删除。

select convert(varbinary, Name) from table

从上面的查询中读取HEX输出应该显示相同的内容。

请阅读this以了解如何编写删除此类字符的函数。

答案 1 :(得分:13)

你可以做一些蛮力,比如删除第一个字符"手动"如果它不是字母数字:

update table
    set name = rtrim(ltrim(case when name not like '[a-zA-Z0-9]%'
                                then stuff(name, 1, 1, '')
                                else name
                           end)
                    );

您还可以搜索并替换该特定字符:

update table
    set name = rtrim(ltrim(replace(name, "big dash", '')));

答案 2 :(得分:9)

请使用以下查询,它将删除空格新行等。

select LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(Name, CHAR(10), CHAR(32)),CHAR(13), CHAR(32)),CHAR(160), CHAR(32)),CHAR(9),CHAR(32))))

答案 3 :(得分:8)

如果你的字符串有一些非unicode字符,那么首先需要删除它们。稍后将从此链接中提供相关函数 - http://iso30-sql.blogspot.com/2010/10/remove-non-printable-unicode-characters.html

首先,使用 -

检查是否有任何奇怪的十六进制字符
select convert(varbinary, Name) from table

然后,使用上面链接中给出的代码。请注意,在使用函数时,将删除方括号,否则代码将不起作用。例如。 [@DatabaseName = 'MyDatabaseName',] [@SchemaName = 'MySchemaName',]

在此之后,您的字符串可能会有一些空格,可以使用 -

删除
UPDATE Table
SET Name = RTRIM(LTRIM(Name))

另请注意,上述链接/下面给出的脚本不适用于 下表 -

CREATE TABLE [dbo].[Junk](
    [JunkHex] nvarchar(50) NULL
) ON [PRIMARY]
GO

GO
INSERT [dbo].[Junk] ([JunkHex]) VALUES (N'Stringğ ')
INSERT [dbo].[Junk] ([JunkHex]) VALUES (N'withħ')
INSERT [dbo].[Junk] ([JunkHex]) VALUES (N'įņvalidđ')
INSERT [dbo].[Junk] ([JunkHex]) VALUES (N'charactersŝ')

这是我上面给出的链接的内容 -

删除SQL Server 2005中的不可打印/ Unicode字符 几个月前,我将一些报表模板从旧版本的Excel( .xls)升级到Excel 2007( .xlsx)。当我尝试生成升级的报告时,我几乎立即遇到了许多问题,因为传入的数据充斥着与XML不能很好地混合的字符。这些数据用于各种报告目的,因此我决定通过删除除可打印的ascii字符以外的所有字符来解决后端问题。

我开始为单个字符串编写一个简单的用户函数,但我认为我可能想要自动执行其中一些清理任务,最后将一些东西放在一起,这样可以提高灵活性。下面创建基本字符串用户函数,以及在列和表级别执行清理的两个过程:

注意 - 以下每个脚本都使用上面的所有脚本。因此,执行所有脚本以获得所有功能。

功能:fn_npclean_string

use [master]
go
set ansi_nulls on
go
set quoted_identifier on
go
CREATE function [dbo].[fn_npclean_string] (
 @strIn as varchar(1000)
)
returns varchar(1000)
as
begin
 declare @iPtr as int
 set @iPtr = patindex('%[^ -~0-9A-Z]%', @strIn COLLATE LATIN1_GENERAL_BIN)
 while @iPtr > 0 begin
  set @strIn = replace(@strIn COLLATE LATIN1_GENERAL_BIN, substring(@strIn, @iPtr, 1), '')
  set @iPtr = patindex('%[^ -~0-9A-Z]%', @strIn COLLATE LATIN1_GENERAL_BIN)
 end
 return @strIn
end

程序:sp_npclean_col

use [master]
go
set ansi_nulls on
go
set quoted_identifier on
go
CREATE procedure [dbo].[sp_npclean_col]
 @DatabaseName varchar(75) = null,
 @SchemaName varchar(75) = null,
 @TableName varchar(75),
 @ColumnName varchar(75)
as
begin
 Declare @FullTableName varchar(100)
 declare @UpdateSQL nvarchar(1000)
 if @DatabaseName is null begin
  set @DatabaseName = db_name()
 end
 if @SchemaName is null begin
  set @SchemaName = schema_name()
 end
 set @FullTableName = '[' + @DatabaseName + '].[' + @SchemaName + '].[' + @TableName + ']'
 set @UpdateSQL = 'update ' + @FullTableName + ' set [' + @ColumnName + '] = dbo.fn_npclean_string([' + @ColumnName + ']) where [' + @ColumnName + '] like ''%[^ -~0-9A-Z]%'''
 exec sp_ExecuteSQL @UpdateSQL
end

程序:sp_npclean_table

use [master]
go
set ansi_nulls on
go
set quoted_identifier on
go
create procedure [dbo].[sp_npclean_table] 
 @TargetDatabase varchar(75) = null,
 @TargetSchema varchar(75) = null,
 @TargetTable varchar(75)
as
begin
 declare @getColSQL nvarchar(750)
 declare @textCol CURSOR
 declare @curCol varchar(75)
 if @TargetDatabase is null begin
  set @TargetDatabase = db_name()
 end
 if @TargetSchema is null begin
  set @TargetSchema = schema_name()
 end
 set @getColSQL =
  'select sc.name
  from ' + @TargetDatabase + '.sys.columns sc
  join ' + @TargetDatabase + '.sys.types st
  on sc.system_type_id = st.system_type_id
  join ' + @TargetDatabase + '.sys.objects so
  on sc.object_id = so.object_id
  join ' + @TargetDatabase + '.sys.schemas ss
  on so.schema_id = ss.schema_id
  where
  so.type = ''U''
  and st.name in (''text'',''ntext'',''varchar'',''char'',''nvarchar'',''nchar'')
  and sc.is_rowguidcol = 0
  and sc.is_identity = 0
  and sc.is_computed = 0
  and so.name = ''' + @TargetTable + '''
  and ss.name = ''' + @TargetSchema + ''''
 set @getColSQL = 'set @inCursor = cursor for ' + @getColSQL + ' open @incursor'
 execute sp_executesql @getColSQL,N'@inCursor cursor out',@inCursor=@textCol OUT
 fetch next from @textCol into @curCol
 while @@fetch_status = 0
 begin
  exec sp_npclean_col @DatabaseName = @TargetDatabase, @SchemaName = @TargetSchema, @TableName = @TargetTable, @ColumnName = @curCol
  fetch next from @textCol into @curCol
 end
 Close @textCol
 DeAllocate @textCol
end

使用这些,可以通过以下方式删除无效字符:

按字符串:

select master.dbo.fn_npclean_string('Stringğ withħ įņvalidđ charactersŝ')

按表格列:

exec master.dbo.sp_npclean_col [@DatabaseName = 'MyDatabaseName',] [@SchemaName = 'MySchemaName',] @TableName = 'MyTableName',  @ColumnName = 'MyColumnName'

按表格:

exec master.dbo.sp_npclean_table [@TargetDatabase = 'MyDatabaseName',] [@TargetSchema = 'MySchemaName',] @TargetTable = 'MyTableName'

答案 4 :(得分:6)

我们必须经常在进行额外处理或将其发送到应用程序中的另一层之前从字符串中删除前导和尾随空格。我们无法始终控制数据的输入方式。数据可能来自另一个系统,数据转换,旧应用程序,EDI,Excel,或来自质量控制较差的应用程序。在某些情况下,可能不会在系统中输入或保存空格,因为字符32是在键盘中输入的空格。如果发生这种情况,用于修剪空格的SQL内置函数不起作用,因此有必要用字符32替换“其他”空白字符。然后LTRIM和RTRIM将按预期工作。

**Select [udfTrim](ColumnName) from Table**

**CREATE FUNCTION [dbo].[udfTrim] 
(
    @StringToClean as varchar(8000)
)**
RETURNS varchar(8000)
AS
BEGIN   
    --Replace all non printing whitespace characers with Characer 32 whitespace
    --NULL
    Set @StringToClean = Replace(@StringToClean,CHAR(0),CHAR(32));
    --Horizontal Tab
    Set @StringToClean = Replace(@StringToClean,CHAR(9),CHAR(32));
    --Line Feed
    Set @StringToClean = Replace(@StringToClean,CHAR(10),CHAR(32));
    --Vertical Tab
    Set @StringToClean = Replace(@StringToClean,CHAR(11),CHAR(32));
    --Form Feed
    Set @StringToClean = Replace(@StringToClean,CHAR(12),CHAR(32));
    --Carriage Return
    Set @StringToClean = Replace(@StringToClean,CHAR(13),CHAR(32));
    --Column Break
    Set @StringToClean = Replace(@StringToClean,CHAR(14),CHAR(32));
    --Non-breaking space
    Set @StringToClean = Replace(@StringToClean,CHAR(160),CHAR(32));

    Set @StringToClean = LTRIM(RTRIM(@StringToClean));
    Return @StringToClean
END

答案 5 :(得分:0)

您可以使用上面的HEX方法,也可以使用ASCII()函数来确定所讨论字符的ASCII代码...

SELECT ASCII(SUBSTRING('  character string', 1, 1)) 
SELECT ASCII(SUBSTRING('  character string', 2, 1))

select只为您指定的字符返回1值。但这对于确定需要替换的ASCII CHAR()值很有帮助。

-Eric Isaacs

答案 6 :(得分:0)

使用它来识别令人反感的字符:

select ascii(substring(' Your string with leading invisible character',1,1));
-- returns something like 160

使用它来替换令人反感的字符

replace(' Your string with leading invisible character', char(160),'')

答案 7 :(得分:-1)

有些情况下LTRIM RTRIM没有做你想要的,对我来说,它发生的原因是当tab键插入数据库时​​我们无法在我们的眼中看到它在这种情况下修剪功能没有工作

试用此代码

UPDATE <TablaName> SET NAME = CAST(LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(value, CHAR(9), ''), CHAR(13), ''), CHAR(10), ''))) AS VARCHAR(50))