PATINDEXを使用して、パターン(文字列)オカレンスの最初のインデックスを見つけることができます。次に、STUFFを使用して、一致したパターン(文字列)に別の文字列を詰め込みます。
各行をループします。不正な各文字を必要なものに置き換えます。あなたの場合、非数値を空白に置き換えてください。内側のループは、現在のセルにループの文字が複数ある場合です。
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
注意:これは遅いです! varchar列があると影響が出る可能性があります。したがって、LTRIMRTRIMを使用すると少し役立つ場合があります。とにかく、遅いです。
クレジットはこのStackOverFlowの回答に割り当てられます。
EDITCreditは@srutzkyにも行きます
編集(@Tmdeanによる)一度に1行を実行する代わりに、この回答をよりセットベースのソリューションに適合させることができます。それでも、1行の数字以外の文字の最大数を繰り返すため、理想的ではありませんが、ほとんどの状況で許容できるはずです。
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;
フィールドがまだスクラブされているかどうかを示すビット列をテーブルに保持すると、効率を大幅に向上させることもできます。 (NULLは私の例では「不明」を表し、列のデフォルトである必要があります。)
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;
スキーマを変更したくない場合は、これを簡単に適応させて、中間結果をテーブル値変数に格納し、最後に実際のテーブルに適用することができます。