U kunt PATINDEX gebruiken om de eerste index van het voorkomen van het patroon (tekenreeks) te vinden. Gebruik dan STUFF om een andere string in het overeenkomende patroon(string) te proppen.
Loop door elke rij. Vervang elk illegaal karakter door wat je wilt. Vervang in uw geval niet-numeriek door spatie. De binnenste lus is als je meer dan één ongeldig teken in een huidige cel hebt, die van de lus.
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
Let op:dit gaat wel langzaam! Het hebben van een varchar-kolom kan van invloed zijn. Dus het gebruik van LTRIM RTRIM kan een beetje helpen. Hoe dan ook, het is traag.
Krediet gaat naar dit StackOverFlow-antwoord.
EDITCredit gaat ook naar @srutzky
Bewerken (door @Tmdean) In plaats van één rij tegelijk te doen, kan dit antwoord worden aangepast aan een meer set-gebaseerde oplossing. Het herhaalt nog steeds het maximum van het aantal niet-numerieke tekens in een enkele rij, dus het is niet ideaal, maar ik denk dat het in de meeste situaties acceptabel zou moeten zijn.
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;
Je kunt de efficiëntie ook behoorlijk verbeteren als je een bitkolom in de tabel aanhoudt die aangeeft of het veld al is geschrobd. (NULL staat in mijn voorbeeld voor "Onbekend" en zou de standaardkolom moeten zijn.)
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;
Als u uw schema niet wilt wijzigen, is dit eenvoudig aan te passen om tussentijdse resultaten op te slaan in een tabelwaardevariabele die aan het einde op de eigenlijke tabel wordt toegepast.