【问题标题】:Trimming text strings in SQL Server 2008在 SQL Server 2008 中修剪文本字符串
【发布时间】:2010-08-15 11:50:59
【问题描述】:

我在 SQL Server 2008 数据库中有一个表。此表有一个名为“名称”的 nvarchar(256) 列。不幸的是,该字段中的值包含额外的空格。例如,名称“Bill”实际上在表中存储为“Bill”。

我想更新此表中的所有记录以删除多余的空格。然而,我惊讶地发现 SQL 没有 TRIM 函数。

如何一次更新所有记录以删除多余的空格?

谢谢!

【问题讨论】:

    标签: sql-server sql-server-2008


    【解决方案1】:

    你确实有一个RTRIM 和一个LTRIM 函数。您可以将它们组合起来以获得您想要的修剪功能。

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

    【讨论】:

      【解决方案2】:

      您可以使用 RTrim 函数从右侧修剪所有空白。使用 LTrim 从左侧修剪所有空白。例如

      UPDATE Table SET Name = RTrim(Name)
      

      或左右修剪

      UPDATE Table SET Name = LTrim(RTrim(Name))
      

      【讨论】:

      • 这个答案应该是公认的,因为LTRIM(RTRIM(Name)) 可能比RTRIM(LTRIM(Name)) 更有效率。
      • 嗯,这取决于内部实现语言。如果是 C/C++,则 LTRIM 必须将字符串字符向左移动,而 RTRIM 只是在右侧位置写入终止 '\0'。因此,RTRIM 之后的 LTRIM 需要移动的字符更少。当然,从大局来看,这并不重要,但还是这样更有效率,交换 LTRIM 和 RTRIM 的成本绝对是 0。
      【解决方案3】:

      SQL Server 没有 TRIM 函数,但它有两个。一个用于专门修剪字符串“前面”的空格(LTRIM),一个用于修剪字符串“末尾”的空格(RTRIM)。

      以下内容将更新表中的每条记录,修剪 varchar/nvarchar 字段的所有无关空间(无论是前面还是结尾):

      UPDATE 
         [YourTableName]
      SET
         [YourFieldName] = LTRIM(RTRIM([YourFieldName]))
      

      (奇怪的是,SSIS(Sql Server 集成服务)确实只有一个 TRIM 函数!)

      【讨论】:

        【解决方案4】:

        我会尝试这样的 Trim 函数,该函数考虑了 Unicode 标准定义的所有空白字符(LTRIM 和 RTRIM 甚至不修剪换行符!):

        IF OBJECT_ID(N'dbo.IsWhiteSpace', N'FN') IS NOT NULL
            DROP FUNCTION dbo.IsWhiteSpace;
        GO
        
        -- Determines whether a single character is white-space or not (according to the UNICODE standard).
        CREATE FUNCTION dbo.IsWhiteSpace(@c NCHAR(1)) RETURNS BIT
        BEGIN
        	IF (@c IS NULL) RETURN NULL;
        	DECLARE @WHITESPACE NCHAR(31);
        	SELECT @WHITESPACE = ' ' + NCHAR(13) + NCHAR(10) + NCHAR(9) + NCHAR(11) + NCHAR(12) + NCHAR(133) + NCHAR(160) + NCHAR(5760) + NCHAR(8192) + NCHAR(8193) + NCHAR(8194) + NCHAR(8195) + NCHAR(8196) + NCHAR(8197) + NCHAR(8198) + NCHAR(8199) + NCHAR(8200) + NCHAR(8201) + NCHAR(8202) + NCHAR(8232) + NCHAR(8233) + NCHAR(8239) + NCHAR(8287) + NCHAR(12288) + NCHAR(6158) + NCHAR(8203) + NCHAR(8204) + NCHAR(8205) + NCHAR(8288) + NCHAR(65279);
        	IF (CHARINDEX(@c, @WHITESPACE) = 0) RETURN 0;
        	RETURN 1;
        END
        GO
        
        IF OBJECT_ID(N'dbo.Trim', N'FN') IS NOT NULL
            DROP FUNCTION dbo.Trim;
        GO
        
        -- Removes all leading and tailing white-space characters. NULL is converted to an empty string.
        CREATE FUNCTION dbo.Trim(@TEXT NVARCHAR(MAX)) RETURNS NVARCHAR(MAX)
        BEGIN
        	-- Check tiny strings (NULL, 0 or 1 chars)
        	IF @TEXT IS NULL RETURN N'';
        	DECLARE @TEXTLENGTH INT = LEN(@TEXT);
        	IF @TEXTLENGTH < 2 BEGIN
        		IF (@TEXTLENGTH = 0) RETURN @TEXT;
        		IF (dbo.IsWhiteSpace(SUBSTRING(@TEXT, 1, 1)) = 1) RETURN '';
        		RETURN @TEXT;
        	END
        	-- Check whether we have to LTRIM/RTRIM
        	DECLARE @SKIPSTART INT;
        	SELECT @SKIPSTART = dbo.IsWhiteSpace(SUBSTRING(@TEXT, 1, 1));
        	DECLARE @SKIPEND INT;
        	SELECT @SKIPEND = dbo.IsWhiteSpace(SUBSTRING(@TEXT, @TEXTLENGTH, 1));
        	DECLARE @INDEX INT;
        	IF (@SKIPSTART = 1) BEGIN
        		IF (@SKIPEND = 1) BEGIN
        			-- FULLTRIM
        			-- Determine start white-space length
        			SELECT @INDEX = 2;
        			WHILE (@INDEX < @TEXTLENGTH) BEGIN -- Hint: The last character is already checked
        				-- Stop loop if no white-space
        				IF (dbo.IsWhiteSpace(SUBSTRING(@TEXT, @INDEX, 1)) = 0) BREAK;
        				-- Otherwise assign index as @SKIPSTART
        				SELECT @SKIPSTART = @INDEX;
        				-- Increase character index
        				SELECT @INDEX = (@INDEX + 1);
        			END
        			-- Return '' if the whole string is white-space
        			IF (@SKIPSTART = (@TEXTLENGTH - 1)) RETURN ''; 
        			-- Determine end white-space length
        			SELECT @INDEX = (@TEXTLENGTH - 1);
        			WHILE (@INDEX > 1) BEGIN 
        				-- Stop loop if no white-space
        				IF (dbo.IsWhiteSpace(SUBSTRING(@TEXT, @INDEX, 1)) = 0) BREAK;
        				-- Otherwise increase @SKIPEND
        				SELECT @SKIPEND = (@SKIPEND + 1);
        				-- Decrease character index
        				SELECT @INDEX = (@INDEX - 1);
        			END
        			-- Return trimmed string
        			RETURN SUBSTRING(@TEXT, @SKIPSTART + 1, @TEXTLENGTH - @SKIPSTART - @SKIPEND);
        		END 
        		-- LTRIM
        		-- Determine start white-space length
        		SELECT @INDEX = 2;
        		WHILE (@INDEX < @TEXTLENGTH) BEGIN -- Hint: The last character is already checked
        			-- Stop loop if no white-space
        			IF (dbo.IsWhiteSpace(SUBSTRING(@TEXT, @INDEX, 1)) = 0) BREAK;
        			-- Otherwise assign index as @SKIPSTART
        			SELECT @SKIPSTART = @INDEX;
        			-- Increase character index
        			SELECT @INDEX = (@INDEX + 1);
        		END
        		-- Return trimmed string
        		RETURN SUBSTRING(@TEXT, @SKIPSTART + 1, @TEXTLENGTH - @SKIPSTART);
        	END ELSE BEGIN
        		-- RTRIM
        		IF (@SKIPEND = 1) BEGIN
        			-- Determine end white-space length
        			SELECT @INDEX = (@TEXTLENGTH - 1);
        			WHILE (@INDEX > 1) BEGIN 
        				-- Stop loop if no white-space
        				IF (dbo.IsWhiteSpace(SUBSTRING(@TEXT, @INDEX, 1)) = 0) BREAK;
        				-- Otherwise increase @SKIPEND
        				SELECT @SKIPEND = (@SKIPEND + 1);
        				-- Decrease character index
        				SELECT @INDEX = (@INDEX - 1);
        			END
        			-- Return trimmed string
        			RETURN SUBSTRING(@TEXT, 1, @TEXTLENGTH - @SKIPEND);
        		END 
        	END
        	-- NO TRIM
        	RETURN @TEXT;
        END
        GO

        【讨论】:

          【解决方案5】:

          我知道这是一个老问题,但我刚刚找到了一个使用 LTRIM 和 RTRIM 创建用户定义函数的解决方案。它不处理字符串中间的双空格。

          然而,解决方案是直截了当的:

          User Defined Trim Function

          【讨论】:

            【解决方案6】:

            没有答案是真的

            真正的答案是 Edit Column to NVARCHAR 并且您发现 Automatically trim Execute 但是这段代码 更新表 SET 名称 = RTRIM(LTRIM(名称)) 仅与 Nvarchar 一起使用,如果与 CHAR 或 NCHAR 一起使用,它将不起作用

            【讨论】:

            • 你期待什么?对于 CHAR 和 NCHAR,字符串具有固定长度。如果您修剪 CHAR(30) 的最后 10 个空字符并再次将其分配给 CHAR(30),则字符串将再次使用空格填充到 30 个字符。
            【解决方案7】:

            这个函数从左到右修剪一个字符串。它还从字符串中删除回车符,这是 LTRIM 和 RTRIM 不执行的操作

            IF OBJECT_ID(N'dbo.TRIM', N'FN') IS NOT NULL
                DROP FUNCTION dbo.TRIM;
            GO
            CREATE FUNCTION dbo.TRIM (@STR NVARCHAR(MAX)) RETURNS NVARCHAR(MAX)
            BEGIN
                RETURN(LTRIM(RTRIM(REPLACE(REPLACE(@STR ,CHAR(10),''),CHAR(13),''))))
            END;
            GO
            

            【讨论】:

            • 你的函数的问题是它不会修剪 CRLF,它们也会在字符串中被替换,这可能是不需要的。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-10-26
            • 2013-01-11
            • 2010-09-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多