SQL:根据第二个表替换多行中的列的一部分

问题描述:

我有一个表(pages),其中包含网页属性,包括页面内容本身的列,NVARCHAR(MAX)列。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,而且我对它相当陌生。非常感谢您提供的任何帮助!

试试这个

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

做的伎俩在这里是一个单语句,非光标方法,它利用了热膨胀系数:

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()一起使用。 –