Para quem usa o SQL Server 2017 ou mais recente
você pode usar a função interna TRIM . Por exemplo:
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'~';
Observe que o comportamento padrão de TRIM
é remover apenas espaços; portanto, para remover também as guias e as novas linhas (CR + LFs), é necessário especificar a characters FROM
cláusula.
Além disso, usei NCHAR(0x09)
os caracteres de tabulação na @Test
variável para que o código de exemplo possa ser copiado e colado e mantenha os caracteres corretos. Caso contrário, as guias serão convertidas em espaços quando esta página for renderizada.
Para quem usa o SQL Server 2016 ou mais antigo
Você pode criar uma função, como um UDF escalar SQLCLR ou um TVF embutido T-SQL (iTVF). O TVF embutido T-SQL seria o seguinte:
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
E executando-o da seguinte maneira:
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;
Devoluções:
proof
----
~this
content~
E você pode usar isso em um UPDATE
usando 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
Como mencionado no começo, isso também é muito fácil via SQLCLR, pois o .NET inclui um Trim()
método que faz exatamente a operação que você deseja. Você pode codificar para chamar SqlString.Value.Trim()
ou simplesmente instalar a versão gratuita da biblioteca SQL # (que eu criei, mas essa função está na versão gratuita) e usar String_Trim (que ocupa apenas espaço em branco) ou String_TrimChars em que você passa os caracteres para aparar dos dois lados (assim como o iTVF mostrado acima).
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];
E ele retorna exatamente a mesma string mostrada acima na saída de exemplo do iTVF. Mas, sendo um UDF escalar, você o usaria da seguinte maneira UPDATE
:
UPDATE tbl
SET tbl.[Column] = SQL#.String_Trim(itvf.[Column])
FROM SchemaName.TableName tbl
Qualquer uma das opções acima deve ser eficiente para o uso em milhões de linhas. Os TVFs embutidos são otimizáveis, diferentemente dos TVFs com várias instruções e dos UDFs escalares T-SQL. Além disso, as UDFs escalares do SQLCLR têm o potencial de serem usadas em planos paralelos, desde que estejam marcadas IsDeterministic=true
e não configurem nenhum tipo de DataAccess como Read
(o padrão para o acesso aos dados do usuário e do sistema é None
), e essas duas condições são true para ambas as funções SQLCLR mencionadas acima.
UPDATE
consulta comoLTRIM
/RTRIM
, algo nas linhas deUPDATE table t SET t.column = TRIM(t.column, CONCAT(CHAR(9), CHAR(10), CHAR(13)))
com umaTRIM( expression, charlist )
função que aceita uma lista de caracteres para aparar como muitas linguagens de script possuem.update
declaração.Eu apenas tive um problema com essa situação específica, eu precisava encontrar e limpar todos os campos com espaços em branco, mas encontrei 4 tipos de espaços em branco possíveis nos campos do meu banco de dados (referência à tabela de códigos ASCII):
Talvez esta consulta possa ajudá-lo.
fonte
Você precisaria analisar o segundo exemplo, porque LTRIM / RTRIM apenas recortam espaços. Você realmente deseja aparar o que o SQL considera dados (/ r, / t, etc). Se você souber os valores que está procurando, use REPLACE para substituí-los. Melhor ainda, escreva uma função e chame-a.
fonte
Se quiser, use minha função elegante:
fonte
O uso da função em dados grandes pode levar muito tempo para ser executado. Eu tenho um conjunto de dados de 8 milhões de linhas, usando a função levou mais de 30 minutos para executar.
replace(replace(replace(replace(@COLUMN,CHAR(9),''),CHAR(10),''),CHAR(13),''),CHAR(32),'')
levou apenas 5 segundos. Obrigado a todos. Vejo você @ sami.almasagedi e @Colin 't Hartfonte