Dành cho ai sử dụng SQL Server 2017 trở lên
bạn có thể sử dụng chức năng tích hợp TRIM . Ví dụ:
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'~';
Xin lưu ý rằng hành vi mặc định của TRIM
là chỉ xóa các khoảng trắng, do đó, để xóa các tab và dòng mới (CR + LFs), bạn cần chỉ định characters FROM
mệnh đề.
Ngoài ra, tôi đã sử dụng NCHAR(0x09)
cho các ký tự tab trong @Test
biến để mã ví dụ có thể được sao chép và dán và giữ lại các ký tự chính xác. Mặt khác, các tab được chuyển đổi thành khoảng trắng khi trang này được hiển thị.
Đối với bất kỳ ai sử dụng SQL Server 2016 trở lên
Bạn có thể tạo một hàm, dưới dạng UDF vô hướng SQLCLR hoặc TVF nội tuyến T-SQL (iTVF). TVF nội tuyến T-SQL sẽ như sau:
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
Và chạy nó như sau:
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;
Trả về:
proof
----
~this
content~
Và bạn có thể sử dụng nó trong việc UPDATE
sử dụng 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
Như đã đề cập ở phần đầu, điều này cũng thực sự dễ dàng thông qua SQLCLR vì .NET bao gồm một Trim()
phương thức thực hiện chính xác thao tác bạn muốn. Bạn có thể mã của bạn riêng để gọi SqlString.Value.Trim()
, hoặc bạn chỉ có thể cài đặt phiên bản miễn phí của SQL # thư viện (mà tôi tạo ra, nhưng chức năng này trong phiên bản miễn phí) và sử dụng một trong hai String_Trim (mà không gian chỉ trắng) hoặc String_TrimChars nơi bạn chuyển các ký tự để cắt từ cả hai phía (giống như iTVF được hiển thị ở trên).
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];
Và nó trả về chuỗi chính xác như được hiển thị ở trên trong đầu ra ví dụ iTVF. Nhưng là một UDF vô hướng, bạn sẽ sử dụng nó như sau trong UPDATE
:
UPDATE tbl
SET tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM SchemaName.TableName tbl
Một trong những điều trên sẽ có hiệu quả để sử dụng trên hàng triệu hàng. TVF nội tuyến có thể tối ưu không giống như TVF đa câu lệnh và UDF vô hướng T-SQL. Và, các UDF vô hướng SQLCLR có tiềm năng được sử dụng trong các kế hoạch song song, miễn là chúng được đánh dấu IsDeterministic=true
và không đặt loại DataAccess thành Read
(mặc định cho cả truy cập dữ liệu Người dùng và Hệ thống None
) và cả hai điều kiện đó là đúng cho cả hai hàm SQLCLR đã lưu ý ở trên.
UPDATE
truy vấn nhưLTRIM
/RTRIM
, một cái gì đó trong một dòngUPDATE table t SET t.column = TRIM(t.column, CONCAT(CHAR(9), CHAR(10), CHAR(13)))
cóTRIM( expression, charlist )
chức năng chấp nhận danh sách các ký tự để cắt giống như nhiều ngôn ngữ scripting có.