Você pode usar PATINDEX para encontrar o primeiro índice da ocorrência do padrão (string). Em seguida, use STUFF para inserir outra string no padrão (string) correspondente.
Faça um loop em cada linha. Substitua cada caractere ilegal pelo que você deseja. No seu caso, substitua não numérico por branco. O loop interno é se você tiver mais de um caractere ilegal em uma célula atual do loop.
DECLARE @counter int
SET @counter = 0
WHILE(@counter < (SELECT MAX(ID_COLUMN) FROM Table))
BEGIN
WHILE 1 = 1
BEGIN
DECLARE @RetVal varchar(50)
SET @RetVal = (SELECT Column = STUFF(Column, PATINDEX('%[^0-9.]%', Column),1, '')
FROM Table
WHERE ID_COLUMN = @counter)
IF(@RetVal IS NOT NULL)
UPDATE Table SET
Column = @RetVal
WHERE ID_COLUMN = @counter
ELSE
break
END
SET @counter = @counter + 1
END
Cuidado:Isso é lento embora! Ter uma coluna varchar pode impactar. Portanto, usar LTRIM RTRIM pode ajudar um pouco. Independentemente disso, é lento.
O crédito vai para esta resposta do StackOverFlow.
EDITCredit também vai para @srutzky
Editar (por @Tmdean) Em vez de fazer uma linha de cada vez, esta resposta pode ser adaptada a uma solução mais baseada em conjuntos. Ele ainda itera o máximo do número de caracteres não numéricos em uma única linha, então não é o ideal, mas acho que deve ser aceitável na maioria das situações.
WHILE 1 = 1 BEGIN
WITH q AS
(SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n
FROM Table)
UPDATE Table
SET Column = STUFF(Column, q.n, 1, '')
FROM q
WHERE Table.ID_Column = q.ID_Column AND q.n != 0;
IF @@ROWCOUNT = 0 BREAK;
END;
Você também pode melhorar bastante a eficiência se mantiver uma coluna de bits na tabela que indica se o campo já foi depurado. (NULL representa "Desconhecido" no meu exemplo e deve ser o padrão da coluna.)
DECLARE @done bit = 0;
WHILE @done = 0 BEGIN
WITH q AS
(SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n
FROM Table
WHERE COALESCE(Scrubbed_Column, 0) = 0)
UPDATE Table
SET Column = STUFF(Column, q.n, 1, ''),
Scrubbed_Column = 0
FROM q
WHERE Table.ID_Column = q.ID_Column AND q.n != 0;
IF @@ROWCOUNT = 0 SET @done = 1;
-- if Scrubbed_Column is still NULL, then the PATINDEX
-- must have given 0
UPDATE table
SET Scrubbed_Column = CASE
WHEN Scrubbed_Column IS NULL THEN 1
ELSE NULLIF(Scrubbed_Column, 0)
END;
END;
Se você não quiser alterar seu esquema, é fácil adaptá-lo para armazenar resultados intermediários em uma variável com valor de tabela que é aplicada à tabela real no final.