Du kan bruge PATINDEX til at finde det første indeks for mønsterets (strengens) forekomst. Brug derefter STUFF til at stoppe en anden streng i det matchede mønster(streng).
Løkke gennem hver række. Erstat hver ulovlig karakter med det, du ønsker. I dit tilfælde skal du erstatte ikke-numerisk med blank. Den indre løkke er, hvis du har mere end et ulovligt tegn i en aktuel celle, det i løkken.
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
Advarsel:Det er dog langsomt! At have en varchar-søjle kan påvirke. Så brug af LTRIM RTRIM kan hjælpe lidt. Uanset hvad er det langsomt.
Kredit går til dette StackOverFlow-svar.
EDITCredit går også til @srutzky
Rediger (af @Tmdean)I stedet for at lave en række ad gangen, kan dette svar tilpasses til en mere sæt-baseret løsning. Den gentager stadig maks. antallet af ikke-numeriske tegn i en enkelt række, så det er ikke ideelt, men jeg tror, det burde være acceptabelt i de fleste 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 også forbedre effektiviteten en del, hvis du fastholder en bit-kolonne i tabellen, der indikerer, om feltet er blevet skrubbet endnu. (NULL repræsenterer "Ukendt" i mit eksempel og burde være kolonnens standard.)
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;
Hvis du ikke ønsker at ændre dit skema, er dette nemt at tilpasse til at gemme mellemresultater i en tabelværdivariabel, som bliver anvendt på den faktiske tabel i slutningen.