Anda dapat menggunakan PATINDEXuntuk menemukan indeks pertama dari kemunculan pola (string). Kemudian gunakan STUFF untuk memasukkan string lain ke dalam pola (string) yang cocok.
Ulangi setiap baris. Ganti setiap karakter ilegal dengan yang Anda inginkan. Dalam kasus Anda, ganti non numerik dengan kosong. Loop dalam adalah jika Anda memiliki lebih dari satu karakter ilegal dalam sel saat ini yang ada di loop.
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
Perhatian:Ini lambat! Memiliki kolom varchar dapat berdampak. Jadi menggunakan LTRIM RTRIM dapat membantu sedikit. Bagaimanapun, ini lambat.
Penghargaan diberikan untuk jawaban StackOverFlow ini.
EDITCredit juga masuk ke @srutzky
Sunting (oleh @Tmdean) Alih-alih melakukan satu baris pada satu waktu, jawaban ini dapat disesuaikan dengan solusi yang lebih berbasis himpunan. Itu masih mengulangi jumlah maksimum karakter non-numerik dalam satu baris, jadi itu tidak ideal, tetapi saya pikir itu harus dapat diterima di sebagian besar situasi.
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;
Anda juga dapat meningkatkan efisiensi cukup banyak jika Anda mempertahankan kolom bit dalam tabel yang menunjukkan apakah bidang tersebut telah digosok. (NULL mewakili "Tidak Diketahui" dalam contoh saya dan seharusnya menjadi kolom default.)
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;
Jika Anda tidak ingin mengubah skema Anda, ini mudah untuk beradaptasi untuk menyimpan hasil antara dalam variabel bernilai tabel yang diterapkan ke tabel sebenarnya di akhir.