对于使用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'~';
请注意,的默认行为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
并如下运行:
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;
返回值:
proof
----
~this
content~
您可以在UPDATE
using中使用它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
如开头所述,通过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];
并且它返回与iTVF示例输出中上面显示的完全相同的字符串。但是作为标量UDF,您可以在UPDATE
:
UPDATE tbl
SET tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM SchemaName.TableName tbl
以上任何一种对于在数百万行中使用都应该是有效的。与多语句TVF和T-SQL标量UDF不同,嵌入式TVF是可优化的。而且,只要将SQLCLR标量UDF标记为IsDeterministic=true
且不将DataAccess的任何一种设置为Read
(用户和系统数据访问的默认值为None
),并且这两种条件均为,则它们就有可能在并行计划中使用。上面提到的两个SQLCLR函数都为true。
UPDATE
查询中使用,例如LTRIM
/RTRIM
,其中的某行UPDATE table t SET t.column = TRIM(t.column, CONCAT(CHAR(9), CHAR(10), CHAR(13)))
包含TRIM( expression, charlist )
接受要修剪的字符列表的函数就像许多脚本语言一样。