MS SQL基于部分匹配替换完整字符串

时间:2016-11-30 21:34:50

标签: sql-server

我想使用SQL UPDATE查询将开始的所有内容替换为“http://example.com,直至下一个双引号并添加“{{3} }”。我还想在双引号之后保留任何内容。

例如:

ID | CONTENT
--------------
1  | Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more.
2  | Read our <a href="http://example.com/terms">Terms</a> by clicking here.

会变成:

ID | CONTENT
--------------
1  | Visit our <a href="http://new-example.com">About Us Page</a> to learn more.
2  | Read our <a href="http://new-example.com">Terms</a> by clicking here.

我正在使用SQLServer 2012进行此操作。

2 个答案:

答案 0 :(得分:3)

您可以使用

代码:

UPDATE myTable
   SET content = STUFF(content, 
                       PATINDEX('%http://example.com%"%', content),
                       CHARINDEX('"', content, PATINDEX('%http://example.com%"%', content)) - PATINDEX('%http://example.com%"%', content),
                       'http://new-example.com')
 WHERE PATINDEX('%http://example.com%"%', content) > 0;

包含测试数据的完整工作示例:

CREATE TABLE #test (content nvarchar(max));
INSERT INTO #test VALUES ('Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more.');
INSERT INTO #test VALUES ('Read our <a href="http://example.com/terms">Terms</a> by clicking here.');
INSERT INTO #test VALUES ('Some other text');

UPDATE #test
   SET content = STUFF(content, 
                       PATINDEX('%http://example.com%"%', content),
                       CHARINDEX('"', content, PATINDEX('%http://example.com%"%', content)) - PATINDEX('%http://example.com%"%', content),
                       'http://new-example.com')
 WHERE PATINDEX('%http://example.com%"%', content) > 0;

SELECT * FROM #test;

DROP TABLE #test;

输入:

Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more.
Read our <a href="http://example.com/terms">Terms</a> by clicking here.
Some other text

输出:

Visit our <a href="http://new-example.com">About Us Page</a> to learn more.
Read our <a href="http://new-example.com">Terms</a> by clicking here.
Some other text

改进建议:

  • 如果困扰你的是同一个PATINDEX表达式重复四次(这会让我感到困扰),请将其包装在CTE中并在UPDATE语句中加入CTE。

答案 1 :(得分:2)

您可以在XML基础上解决此问题:

DECLARE @tbl TABLE(ID INT, CONTENT VARCHAR(MAX));
INSERT INTO @tbl VALUES
 (1,'Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more.')
,(2,'Read our <a href="http://example.com/terms">Terms</a> by clicking here.');

DECLARE @ReplaceWith VARCHAR(100)='http://new-example.com';

WITH UpdateableCTE AS
(
    SELECT ID
          ,CONTENT
          ,CAST
            (
                CAST('<root>' + CONTENT + '</root>' AS XML).query
                (N'
                    <r>
                    {(root/text())[1]}
                    <a href="{sql:variable("@ReplaceWith")}">
                    {(/root/a/text())[1]}
                    </a>
                    {(root/text())[2]}
                    </r>
                ') AS varchar(MAX)
            ) AS NewContent
    FROM @tbl
)
UPDATE UpdateableCTE SET CONTENT=SUBSTRING(NewContent,4,LEN(NewContent)-7);

SELECT * FROM @tbl;

简短说明: 在开头添加<root>并在末尾添加</root>会将您的代码段转换为有效的XML。 XML方法.query允许使用FLWOR - 代码。给定示例以根节点<r>开头,读取第一个text(),然后添加<a> - 元素和href属性,该属性填充了SQL:变量。然后是text()中的<a>,结束</a>和根节点的第二个文本。

返回的XML已投放到VARCHAR,而SUBSTRING用于删除<r>...</r>