Bạn có thể sử dụng PATINDEX để tìm chỉ mục đầu tiên của lần xuất hiện của mẫu (chuỗi). Sau đó, sử dụng STUFF để nhồi một chuỗi khác vào mẫu (chuỗi) đã khớp.
Lặp qua từng hàng. Thay thế mỗi ký tự bất hợp pháp bằng những gì bạn muốn. Trong trường hợp của bạn, hãy thay thế không phải số bằng trống. Vòng lặp bên trong là nếu bạn có nhiều hơn một ký tự không hợp lệ trong ô hiện tại của vòng lặp.
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
Thận trọng:Tuy nhiên, điều này là chậm! Có một cột varchar có thể ảnh hưởng. Vì vậy, việc sử dụng LTRIM RTRIM có thể giúp ích một chút. Bất kể, nó là chậm.
Tín dụng thuộc về câu trả lời StackOverFlow này.
EDITCredit cũng được chuyển đến @srutzky
Chỉnh sửa (bởi @Tmdean) Thay vì thực hiện từng hàng một, câu trả lời này có thể được điều chỉnh cho phù hợp với một giải pháp dựa trên tập hợp hơn. Nó vẫn lặp lại số ký tự không phải số tối đa trong một hàng, vì vậy nó không phải là lý tưởng, nhưng tôi nghĩ nó nên được chấp nhận trong hầu hết các trường hợp.
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;
Bạn cũng có thể cải thiện hiệu quả khá nhiều nếu bạn duy trì một cột bit trong bảng cho biết trường đã được quét chưa. (NULL đại diện cho "Không xác định" trong ví dụ của tôi và phải là cột mặc định.)
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;
Nếu bạn không muốn thay đổi giản đồ của mình, điều này rất dễ dàng điều chỉnh để lưu trữ các kết quả trung gian trong một biến có giá trị bảng được áp dụng cho bảng thực tế ở cuối.