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 열이 있으면 영향을 미칠 수 있습니다. 따라서 LTRIM RTRIM을 사용하면 도움이 될 수 있습니다. 어쨌든 느립니다.
신용은 이것에 간다 StackOverFlow 답변에 .
편집 크레딧도 @srutzky로 이동합니다.
Edit (by @Tmdean) 한 번에 한 행을 수행하는 대신이 답변을보다 집합 기반 솔루션에 적용 할 수 있습니다. 여전히 단일 행에서 숫자가 아닌 문자 수의 최대 값을 반복하므로 이상적이지는 않지만 대부분의 상황에서 허용되어야한다고 생각합니다.
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;
UPDATE table
SET Scrubbed_Column = CASE
WHEN Scrubbed_Column IS NULL THEN 1
ELSE NULLIF(Scrubbed_Column, 0)
END;
END;
스키마를 변경하지 않으려면 마지막에 실제 테이블에 적용되는 테이블 값 변수에 중간 결과를 저장하도록 쉽게 조정할 수 있습니다.