Możesz użyć PATINDEX, aby znaleźć pierwszy indeks wystąpienia wzorca (łańcucha). Następnie użyj STUFF, aby wstawić kolejny ciąg do dopasowanego wzorca (ciągu).
Przeprowadź pętlę przez każdy rząd. Zastąp każdy nielegalny znak tym, co chcesz. W twoim przypadku zamień nienumeryczne na puste. Wewnętrzna pętla występuje, gdy w bieżącej komórce znajduje się więcej niż jeden niedozwolony znak niż w pętli.
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
Uwaga:to jednak jest powolne! Posiadanie kolumny varchar może mieć wpływ. Więc użycie LTRIM RTRIM może trochę pomóc. Niezależnie od tego jest powolny.
Kredyt trafia do tej odpowiedzi StackOverFlow.
EDITCredit trafia również do @srutzky
Edytuj (by @Tmdean)Zamiast robić jeden wiersz na raz, tę odpowiedź można dostosować do rozwiązania bardziej opartego na zbiorach. Nadal iteruje maksymalną liczbę znaków nienumerycznych w jednym wierszu, więc nie jest to idealne rozwiązanie, ale myślę, że powinno być akceptowalne w większości sytuacji.
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;
Możesz również znacznie poprawić wydajność, jeśli utrzymasz kolumnę bitów w tabeli, która wskazuje, czy pole zostało już wyczyszczone. (NULL oznacza „Nieznany” w moim przykładzie i powinien być domyślną kolumną.)
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;
Jeśli nie chcesz zmieniać schematu, łatwo jest go dostosować do przechowywania wyników pośrednich w zmiennej o wartości tabeli, która na końcu jest stosowana do rzeczywistej tabeli.