2011-08-26 3 views
4

페이지 콘텐츠 자체의 열인 NVARCHAR(MAX) 열을 포함하여 웹 페이지의 속성을 보유하는 테이블 (pages)이 있습니다.SQL : 두 번째 테이블을 기반으로 여러 행에있는 열의 일부를 대체하십시오.

해당 열 내에서 많은 텍스트 문자열을 찾아 교체하고 다른 텍스트 문자열로 바꿔야합니다. 이러한 상관 관계는 두 번째 표 (moving)에 있으며 oldValuenewValue 열입니다.

따라서, 예를 들어,이 같은 두 개의 테이블로 시작 해요 경우 :

페이지 테이블 :

ID Content 
1 Words words Ancient words 
2 Blah blah OutWithTheOld blah 
3 Etc etc Useless etc 

테이블 이동 :

OldValue   NewValue 
Ancient   Better 
OutWithTheOld  InWithTheNew 
Useless   Useful 

합니다. .. Replace와 같은 페이지 테이블을 남겨 두는 방법이 필요합니다.

ID Content 
1 Words words Better words 
2 Blah blah InWithTheNew blah 
3 Etc etc Useful etc 

페이지 테이블에 주어진 레코드가 여러 교체가 필요합니다 가능성이있다, 저기 페이지 기록이 어느 하나, 또는 여러 필요 교체가 없습니다 여부를 예측하는 방법은 없습니다, 또는 moving.oldvalue에서 어떤 값이 될 것이다 발견되어 교체해야합니다.

저는 SQL Server 2008을 사용하고 있으며 상당히 익숙합니다. 어떤 도움을 주셔서 감사드립니다.

답변

2

여기에 CTE를 사용합니다 하나의 문, 비 커서 방식의 I는 일반적으로 커서를 좋아하지 않지만이

DECLARE @OldV NVARCHAR(32) -- Adjust for your field sizes in MOVING 
DECLARE @NEWV NVARCHAR(32) 

DECLARE db_cursor CURSOR FOR 
SELECT * 
FROM Moving 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @OldV,@newV 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    UPDATE Pages SET content=REPLACE(content,@oldV,@NewV) 
     WHERE content LIKE '%'[email protected]+'%' 
     FETCH NEXT FROM db_cursor INTO @oldV,@NewV 
END 

CLOSE db_cursor 
DEALLOCATE db_cursor 

이 당신

+0

와우! 완전히 나를 이길 수있어. 변수 이름 외에도 내 코드는 여러분의 것과 거의 비슷하게 보입니다! – Zach

+0

위대한 마음은 같은 채널에서 실행됩니까? – Sparky

+0

가장 확실합니다! – Zach

3

의 트릭을해야보십시오 :

WITH CTE(iteration, page_id, content) AS (
    SELECT 
     0, 
     P.page_id, 
     REPLACE(P.content, M1.old_value, M1.new_value) 
    FROM 
     Pages P 
    INNER JOIN Moving M1 ON 
     P.content LIKE '%' + M1.old_value + '%' 
    WHERE 
     NOT EXISTS (SELECT * FROM Moving M2 WHERE P.content LIKE '%' + M2.old_value + '%' AND M2.moving_id < M1.moving_id) 
    UNION ALL 
    SELECT 
     CTE.iteration + 1, 
     CTE.page_id, 
     REPLACE(CTE.content, M3.old_value, M3.new_value) 
    FROM 
     CTE 
    INNER JOIN Moving M3 ON 
     CTE.content LIKE '%' + M3.old_value + '%' 
    WHERE 
     NOT EXISTS (SELECT * FROM Moving M4 WHERE CTE.content LIKE '%' + M4.old_value + '%' AND M4.moving_id < M3.moving_id) 
) 
UPDATE P2 
SET 
    content = CTE1.content 
FROM 
    Pages P2 
INNER JOIN CTE CTE1 ON 
    CTE1.page_id = P2.page_id AND 
    NOT EXISTS (SELECT * FROM CTE CTE2 WHERE page_id = P2.page_id AND CTE2.iteration > CTE1.iteration) 
+0

+1, 재귀 CTE도 고려했지만 row_number()와 함께 사용합니다. –

관련 문제