Du kan använda PATINDEX för att hitta det första indexet för mönstrets (strängens) förekomst. Använd sedan STUFF för att stoppa in ytterligare en sträng i mönstret(strängen) som matchas.
Gå igenom varje rad. Byt ut alla olagliga tecken med vad du vill ha. Ersätt i ditt fall icke-numerisk med blank. Den inre slingan är om du har mer än ett olagligt tecken i en aktuell cell det i slingan.
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
Varning:Detta är dock långsamt! Att ha en varcharkolonn kan påverka. Så att använda LTRIM RTRIM kan hjälpa lite. Oavsett, det går långsamt.
Tack till det här StackOverFlow-svaret.
EDITCredit går också till @srutzky
Redigera (av @Tmdean)Istället för att göra en rad i taget kan det här svaret anpassas till en mer uppsättningsbaserad lösning. Den upprepar fortfarande maxtalet för antalet icke-numeriska tecken på en enda rad, så det är inte idealiskt, men jag tror att det borde vara acceptabelt i de flesta situationer.
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;
Du kan också förbättra effektiviteten ganska mycket om du behåller en bitkolumn i tabellen som anger om fältet har skurats ännu. (NULL representerar "Okänd" i mitt exempel och bör vara standardkolumnen.)
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;
Om du inte vill ändra ditt schema är detta lätt att anpassa för att lagra mellanresultat i en tabellvärderad variabel som appliceras på den faktiska tabellen i slutet.