Puede usar PATINDEX para encontrar el primer índice de la ocurrencia del patrón (cadena). Luego use STUFF para rellenar otra cadena en el patrón (cadena) coincidente.
Bucle a través de cada fila. Reemplaza cada carácter ilegal con lo que quieras. En su caso, reemplace no numérico con espacio en blanco. El ciclo interno es si tiene más de un carácter ilegal en una celda actual, el del ciclo.
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
Precaución:¡Esto es lento! Tener una columna varchar puede afectar. Entonces, usar LTRIM RTRIM puede ayudar un poco. De todos modos, es lento.
El crédito es para esta respuesta de StackOverFlow.
EDITCredit también va para @srutzky
Editar (por @Tmdean) En lugar de hacer una fila a la vez, esta respuesta se puede adaptar a una solución más basada en conjuntos. Todavía itera el número máximo de caracteres no numéricos en una sola fila, por lo que no es ideal, pero creo que debería ser aceptable en la mayoría de las situaciones.
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;
También puede mejorar bastante la eficiencia si mantiene una columna de bits en la tabla que indica si el campo ya se ha limpiado. (NULL representa "Desconocido" en mi ejemplo y debería ser la columna predeterminada).
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;
Si no desea cambiar su esquema, esto es fácil de adaptar para almacenar resultados intermedios en una variable con valor de tabla que se aplica a la tabla real al final.