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

发布于 2024-12-01 12:10:05 字数 891 浏览 1 评论 0原文

我有一个表 (pages),它保存网页的属性,其中包括页面内容本身的列,即 NVARCHAR(MAX) 列。

在该列中,我需要查找并替换一堆文本字符串,并将它们替换为其他文本字符串;这些相关性位于第二个表 (moving) 中,其中包含 oldValuenewValue 列。

因此,例如,如果我从这样的两个表开始:

pages table:

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

moving table:

OldValue          NewValue
Ancient           Better
OutWithTheOld     InWithTheNew
Useless           Useful

...我需要一种方法来制作替换,留下页表如下:

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

页表中的给定记录可能需要多次替换,并且无法预测页记录是否没有、一个或多个必要的替换,或者来自 的哪些值moving.oldvalue 将被发现并需要被替换。

我正在使用 SQL Server 2008,而且我对它还很陌生。预先非常感谢您提供的任何帮助!

I have a table (pages) that holds properties for web pages, including a column for the page content itself, an NVARCHAR(MAX) column.

Within that column, I need to find and replace a bunch of text strings and replace them with other text strings; these correlations are in a second table (moving), with an oldValue and newValue column.

So, for example, if I'm starting with the two tables like this:

pages table:

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

moving table:

OldValue          NewValue
Ancient           Better
OutWithTheOld     InWithTheNew
Useless           Useful

...I need a way of making a Replace that leaves the pages table like this:

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

It is possible that a given record in the pages table will need multiple replacements, and there's no way of predicting whether a pages record will have none, one, or many necessary replacements, or which values from moving.oldvalue will be found and need to be replaced.

I'm using SQL Server 2008, and I'm fairly new to it. Thanks so much in advance for any help you can give!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一生独一 2024-12-08 12:10:06

这是一个使用 CTE 的单语句、非游标方法:

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)

Here's a single-statement, non-cursor method which makes use of a CTE:

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)
两人的回忆 2024-12-08 12:10:06

试试这个

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 '%'+@OldV+'%'
       FETCH NEXT FROM db_cursor INTO @oldV,@NewV
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

虽然我通常不喜欢光标,但这应该对你有用

Try this

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 '%'+@OldV+'%'
       FETCH NEXT FROM db_cursor INTO @oldV,@NewV
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

Although I generally don't like cursors, this should do the trick for you

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文