修剪空白(空格、制表符、换行符)

Gio*_*ato 13 sql-server t-sql sql-server-2014 string-manipulation

我在 SQL Server 2014 上,我需要从列内容的开头和结尾清除空格,其中空格可以是简单的空格、制表符或换行符(\n\r\n);例如

'    this content    '                          should become 'this content'
'  \r\n   \t\t\t this \r\n content \t  \r\n   ' should become 'this \r\n content'
Run Code Online (Sandbox Code Playgroud)

等等。

我只能实现第一个案例

UPDATE table t SET t.column = LTRIM(RTRIM(t.column))
Run Code Online (Sandbox Code Playgroud)

但对于其他情况,它不起作用。

Sol*_*zky 11

对于使用 SQL Server 2017 或更高版本的任何人

您可以使用TRIM内置函数。例如:

DECLARE @Test NVARCHAR(4000);
SET @Test = N'  
    ' + NCHAR(0x09) + N'  ' + NCHAR(0x09) + N' this 
 ' + NCHAR(0x09) + NCHAR(0x09) + N'  content' + NCHAR(0x09) + NCHAR(0x09) + N'  
' + NCHAR(0x09) + N' ' + NCHAR(0x09) + NCHAR(0x09) + N'     ';

SELECT N'~'
        + TRIM(NCHAR(0x09) + NCHAR(0x20) + NCHAR(0x0D) + NCHAR(0x0A) FROM @Test)
        + N'~';
Run Code Online (Sandbox Code Playgroud)

请注意, 的默认行为TRIM是仅删除空格,因此为了同时删除制表符和换行符(CR + LF),您需要指定characters FROM子句。

此外,我NCHAR(0x09)@Test变量中使用了制表符,以便可以复制和粘贴示例代码并保留正确的字符。否则,在呈现此页面时,制表符会转换为空格。

对于使用 SQL Server 2016 或更早版本的任何人

您可以将函数创建为 SQLCLR 标量 UDF 或 T-SQL 内联 TVF (iTVF)。T-SQL 内联 TVF 如下所示:

CREATE
--ALTER
FUNCTION dbo.TrimChars(@OriginalString NVARCHAR(4000), @CharsToTrim NVARCHAR(50))
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN
WITH cte AS
(
  SELECT PATINDEX(N'%[^' + @CharsToTrim + N']%', @OriginalString) AS [FirstChar],
         PATINDEX(N'%[^' + @CharsToTrim + N']%', REVERSE(@OriginalString)) AS [LastChar],
        LEN(@OriginalString + N'~') - 1 AS [ActualLength]
)
SELECT cte.[ActualLength],
       [FirstChar],
       ((cte.[ActualLength] - [LastChar]) + 1) AS [LastChar],
       SUBSTRING(@OriginalString, [FirstChar],
                 ((cte.[ActualLength] - [LastChar]) - [FirstChar] + 2)) AS [FixedString]
FROM   cte;
GO
Run Code Online (Sandbox Code Playgroud)

并按如下方式运行它:

DECLARE @Test NVARCHAR(4000);
SET @Test = N'  
    ' + NCHAR(0x09) + N'  ' + NCHAR(0x09) + N' this 
 ' + NCHAR(0x09) + NCHAR(0x09) + N'  content' + NCHAR(0x09) + NCHAR(0x09) + N'  
' + NCHAR(0x09) + N' ' + NCHAR(0x09) + NCHAR(0x09) + N'     ';

SELECT N'~' + tc.[FixedString] + N'~' AS [proof]
FROM   dbo.TrimChars(@Test, NCHAR(0x09) + NCHAR(0x20) + NCHAR(0x0D) + NCHAR(0x0A)) tc;
Run Code Online (Sandbox Code Playgroud)

返回:

proof
----
~this 
              content~
Run Code Online (Sandbox Code Playgroud)

你可以在UPDATEusing 中使用它CROSS APPLY

UPDATE tbl
SET    tbl.[Column] = itvf.[FixedString]
FROM   SchemaName.TableName tbl
CROSS APPLY  dbo.TrimChars(tbl.[Column],
                           NCHAR(0x09) + NCHAR(0x20) + NCHAR(0x0D) + NCHAR(0x0A)) itvf
Run Code Online (Sandbox Code Playgroud)

正如开头所提到的,这也很容易通过 SQLCLR 实现,因为 .NET 包含了一个Trim()完全执行您想要的操作的方法。您可以编写自己的代码来调用SqlString.Value.Trim(),或者您可以只安装SQL#库的免费版本(我创建的,但此函数在免费版本中)并使用String_Trim(只执行空格)或String_TrimChars其中您传入要从两侧修剪的字符(就像上面显示的 iTVF 一样)。

DECLARE @Test NVARCHAR(4000);
SET @Test = N'  
    ' + NCHAR(0x09) + N'  ' + NCHAR(0x09) + N' this 
 ' + NCHAR(0x09) + NCHAR(0x09) + N'  content' + NCHAR(0x09) + NCHAR(0x09) + N'  
' + NCHAR(0x09) + N' ' + NCHAR(0x09) + NCHAR(0x09) + N'     ';

SELECT N'~' + SQL#.String_Trim(@Test) + N'~' AS [proof];
Run Code Online (Sandbox Code Playgroud)

它返回与上面 iTVF 示例输出中显示的完全相同的字符串。但是作为一个标量 UDF,您可以在一个 中按如下方式使用它UPDATE

UPDATE tbl
SET    tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM   SchemaName.TableName tbl
Run Code Online (Sandbox Code Playgroud)

以上任一方法对于跨数百万行使用都应该是有效的。与多语句 TVF 和 T-SQL 标量 UDF 不同,内联 TVF 是可优化的。并且,SQLCLR 标量 UDF 有可能用于并行计划,只要它们被标记为IsDeterministic=true并且不将任一类型的 DataAccess 设置为Read(用户和系统数据访问的默认值是None),并且这两个条件都是上面提到的两个 SQLCLR 函数都为真。