You can use PATINDEX to search for the first occurrence index of a pattern (string). Then use STUFF to fill another line to match the pattern (line).
Scroll through each line. Replace all illegal characters with whatever you want. In your case, replace a non-numeric value with an empty one. An inner loop is if you have more than one illegal character in the current loop cell.
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
Attention! This is slow! The presence of a varchar column may be affected. Therefore, using LTRIM RTRIM may help a little. Despite this, it is slow.
Credit goes to this answer on StackOverFlow.
CHANGE Credit is also sent to @srutzky
Edit (by @Tmdean) Instead of doing one line at a time, this answer can be adapted to a more multi-based solution. It still iterates the maximum number of non-numeric characters on one line, so it is not perfect, but I think this should be acceptable in most situations.
WHILE 1 = 1 BEGIN WITH q AS (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n FROM Table) UPDATE Table SET Column = STUFF(Column, qn, 1, '') FROM q WHERE Table.ID_Column = q.ID_Column AND qn != 0; IF @@ROWCOUNT = 0 BREAK; END;
You can also improve efficiency quite a bit if you maintain a column bit in a table that indicates whether the field has been cleared. (NULL represents "Unknown" in my example and should be the default column.)
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, qn, 1, ''), Scrubbed_Column = 0 FROM q WHERE Table.ID_Column = q.ID_Column AND qn != 0; IF @@ROWCOUNT = 0 SET @done = 1;
If you do not want to change your schema, this is easy to adapt to store intermediate results in a table variable that applies to the actual table at the end.