Vous pouvez utiliser PATINDEX pour trouver le premier index de l'occurrence du modèle (chaîne). Utilisez ensuite STUFF pour insérer une autre chaîne dans le modèle (chaîne) correspondant.
Faites une boucle dans chaque rangée. Remplacez chaque caractère illégal par ce que vous voulez. Dans votre cas, remplacez non numérique par un espace. La boucle interne est si vous avez plus d'un caractère illégal dans une cellule actuelle celle de la boucle.
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 :c'est lent cependant ! Avoir une colonne varchar peut avoir un impact. Donc, utiliser LTRIM RTRIM peut aider un peu. Quoi qu'il en soit, c'est lent.
Le crédit revient à cette réponse StackOverFlow.
EDITCredit va également à @srutzky
Modifier (par @Tmdean)Au lieu de faire une ligne à la fois, cette réponse peut être adaptée à une solution plus basée sur un ensemble. Il itère toujours le maximum du nombre de caractères non numériques dans une seule ligne, donc ce n'est pas idéal, mais je pense que cela devrait être acceptable dans la plupart des 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, q.n, 1, '')
FROM q
WHERE Table.ID_Column = q.ID_Column AND q.n != 0;
IF @@ROWCOUNT = 0 BREAK;
END;
Vous pouvez également améliorer considérablement l'efficacité si vous maintenez une colonne de bits dans le tableau qui indique si le champ a déjà été nettoyé. (NULL représente "Inconnu" dans mon exemple et devrait être la colonne par défaut.)
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;
Si vous ne souhaitez pas modifier votre schéma, il est facile de l'adapter pour stocker les résultats intermédiaires dans une variable de table qui est appliquée à la table réelle à la fin.