Для тех, кто использует 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 )
функцией, принимающей список символов для обрезки как и многие языки сценариев.update
утверждении.У меня просто была проблема с этой конкретной ситуацией, мне нужно было найти и очистить каждое поле с пробелами, но я нашел 4 типа возможных пробелов в полях базы данных (ссылка на таблицу кодов ASCII):
Может быть, этот запрос может помочь вам.
источник
Вам придется проанализировать второй пример, потому что LTRIM / RTRIM только обрезают пробелы. Вы действительно хотите обрезать то, что SQL считает данными (/ r, / t и т. Д.). Если вы знаете значения, которые ищете, просто используйте REPLACE для их замены. Еще лучше написать функцию и вызвать ее.
источник
Если хотите, используйте мою элегантную функцию:
источник
Использование функции для больших данных может занять много времени. У меня есть набор данных из 8 миллионов строк, выполнение функции заняло более 30 минут.
replace(replace(replace(replace(@COLUMN,CHAR(9),''),CHAR(10),''),CHAR(13),''),CHAR(32),'')
заняло всего 5 сек. Спасибо всем. Я вижу тебя @ sami.almasagedi и @Colin 't Hartисточник