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