Для всіх, хто використовує 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 Scalar UDF, або T-SQL Inline TVF (iTVF). TF-SQL Inline 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
використанні 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. Але будучи скалярною АДС, ви використовуєте її в наступному UPDATE
:
UPDATE tbl
SET tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM SchemaName.TableName tbl
Будь-яке з перерахованих вище має бути ефективним для використання у мільйонах рядків. Вбудовані телевізійні канали оптимізуються на відміну від ТВФ з кількома заявами та скалярними UDF T-SQL. І, скалярні UDF SQLCLR можуть використовуватись у паралельних планах, якщо вони позначені як IsDeterministic=true
і не встановлюють жодного типу DataAccess Read
(за замовчуванням для доступу користувачів та системних даних None
), і обидва ці умови є справедливо для обох зазначених вище функцій SQLCLR.
UPDATE
запиті, якLTRIM
/RTRIM
, щось у рядкахUPDATE table t SET t.column = TRIM(t.column, CONCAT(CHAR(9), CHAR(10), CHAR(13)))
ізTRIM( expression, charlist )
функцією, яка приймає список символів для обрізки як у багатьох мов сценаріїв.