Dla każdego używającego SQL Server 2017 lub nowszego
możesz użyć wbudowanej funkcji TRIM . Na przykład:
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'~';
Pamiętaj, że domyślnym zachowaniem TRIM
jest usuwanie tylko spacji, więc aby usunąć tabulacje i znaki nowej linii (CR + LF), musisz określić characters FROM
klauzulę.
Użyłem NCHAR(0x09)
również znaków tabulacji w @Test
zmiennej, aby przykładowy kod można było skopiować i wkleić i zachować prawidłowe znaki. W przeciwnym razie karty są konwertowane na spacje podczas renderowania tej strony.
Dla każdego używającego SQL Server 2016 lub starszego
Możesz utworzyć funkcję, jako SQLCLR Scalar UDF lub T-SQL Inline TVF (iTVF). T-SQL Inline TVF wyglądałby następująco:
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
I uruchom go w następujący sposób:
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;
Zwroty:
proof
----
~this
content~
I możesz tego użyć za UPDATE
pomocą 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
Jak wspomniano na początku, jest to również bardzo łatwe dzięki SQLCLR, ponieważ .NET zawiera Trim()
metodę, która wykonuje dokładnie taką operację, jakiej chcesz. Możesz albo zakodować swój własny kod wywołujący SqlString.Value.Trim()
, albo możesz po prostu zainstalować darmową wersję biblioteki SQL # (którą utworzyłem, ale ta funkcja jest w wersji darmowej) i użyć albo String_Trim (który robi tylko białe znaki ) lub String_TrimChars gdzie przekazujesz znaki do przycinania z obu stron (tak jak pokazano powyżej 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];
I zwraca dokładnie ten sam ciąg, jak pokazano powyżej w przykładowym wyjściu iTVF. Ale będąc skalarnym UDF, użyłbyś go w następujący sposób UPDATE
:
UPDATE tbl
SET tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM SchemaName.TableName tbl
Każdy z powyższych powinien być efektywny w użyciu w milionach wierszy. Inline TVF są optymalizowane w przeciwieństwie do TVF z wieloma instrukcjami i skalarnych UDF T-SQL. Skalarne UDF SQLCLR mają potencjał do zastosowania w planach równoległych, o ile są oznaczone jako IsDeterministic=true
i nie ustawiają żadnego typu DataAccess na Read
(domyślny dla dostępu do danych użytkownika i systemu to None
), a oba te warunki są true dla obu wymienionych powyżej funkcji SQLCLR.
UPDATE
zapytania, np.LTRIM
/RTRIM
, Coś w liniiUPDATE table t SET t.column = TRIM(t.column, CONCAT(CHAR(9), CHAR(10), CHAR(13)))
zTRIM( expression, charlist )
funkcją akceptującą listę znaków do przycięcia jak wiele języków skryptowych.update
oświadczeniu.Właśnie miałem problem z tą konkretną sytuacją, musiałem znaleźć i wyczyścić każde pole białymi spacjami, ale znalazłem 4 rodzaje możliwych białych spacji w polach bazy danych (odwołanie do tabeli kodów ASCII):
Może to zapytanie może ci pomóc.
źródło
Musisz przeanalizować drugi przykład, ponieważ LTRIM / RTRIM tylko przycinają spacje. Naprawdę chcesz przyciąć to, co SQL uważa za dane (/ r, / t itp.). Jeśli znasz wartości, których szukasz, po prostu użyj REPLACE, aby je zastąpić. Jeszcze lepiej, napisz funkcję i wywołaj ją.
źródło
Jeśli chcesz, skorzystaj z mojej eleganckiej funkcji:
źródło
Korzystanie z funkcji w przypadku dużych danych może trwać długo. Mam zestaw danych składający się z 8 milionów wierszy, użycie funkcji zajęło mi ponad 30 minut.
replace(replace(replace(replace(@COLUMN,CHAR(9),''),CHAR(10),''),CHAR(13),''),CHAR(32),'')
zajęło tylko 5 sekund. Dziękuje wszystkim. Widzę cię @ sami.almasagedi i @Colin 't Hartźródło