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
您可以使用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
变量中使用了制表符,以便可以复制和粘贴示例代码并保留正确的字符。否则,在呈现此页面时,制表符会转换为空格。
您可以将函数创建为 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)
你可以在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
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 函数都为真。