SQL 服务器:更新以仅匹配和替换确切的单词
SQL Server: update to match and replace only exact words
我想匹配一个确切的词并将其替换为另一个词。
这是我正在使用的 SQL 服务器查询:
UPDATE BODYCONTENT
SET BODY = CAST(REPLACE(CAST(BODY AS NVARCHAR(MAX)), 'Test' , 'prod') AS NTEXT)
WHERE BODY COLLATE Latin1_General_CI_AS LIKE '%Test%' COLLATE Latin1_General_CI_AS;
这个查询在做什么:
'Test'、'test'、'TEST' 更新为 'prod' -- 这是预期的。
'Test2'、'TestTest'、'Fastest' 更新为 'prod' - 我想避免这种行为。
请帮忙
我试过但没有成功的其他查询:
UPDATE BODYCONTENT
SET BODY = CAST(REPLACE(CAST(BODY AS NVARCHAR(MAX)), 'Test' , 'prod') AS NTEXT)
WHERE BODY COLLATE Latin1_General_CI_AS LIKE '%[^A-Za-z0-9]Test[^A-Za-z0-9]%' COLLATE Latin1_General_CI_AS;
当我使用以下查询为 'Test' 执行 select 时:
SELECT *
FROM dbo.BODYCONTENT
WHERE CONVERT(NVARCHAR(MAX), BODY) = N'Test';
它没有返回任何东西。但我可以使用以下查询获得结果:
SELECT BODY
FROM dbo.BODYCONTENT
WHERE BODY LIKE '%Test%';
SELECT BODY
FROM dbo.BODYCONTENT
WHERE BODY COLLATE Latin1_General_CI_AS like '%TEST%' COLLATE Latin1_General_CI_AS;
这是列值:
Test testtest Test1 Test TEST
预期结果:
prod testtest Test1 prod prod
当前结果:
prod prodprod prod1 prod prod
我的印象是 test
的所有不同版本都在同一行值内,这就是为什么您说建议的 like 'test'
不起作用。
基于此,下面的内容相当丑陋,但可以满足您的要求:
declare @t table(s ntext);
insert into @t values('Test testtest Test1 Test TEST');
select s as Original
,ltrim(rtrim(replace(
replace(
replace(N' ' + cast(s as nvarchar(max)) + N' ' -- Add a single space before and after value,
,' ','<>' -- then replace all spaces with any two characters.
)
,'>test<','>prod<' -- Use these two characters to identify single instances of 'test'
)
,'<>',' ' -- Then replace the delimiting characters with spaces and trim the value.
)
)
) as Updated
from @t;
输出:
+-------------------------------+-------------------------------+
| Original | Updated |
+-------------------------------+-------------------------------+
| Test testtest Test1 Test TEST | prod testtest Test1 prod prod |
+-------------------------------+-------------------------------+
使用 <>
代替空格是由于 SQL 服务器的默认行为忽略字符串比较中的尾随空格。这些可以是任意两个字符,但我觉得它们在美学上令人愉悦。
我想匹配一个确切的词并将其替换为另一个词。
这是我正在使用的 SQL 服务器查询:
UPDATE BODYCONTENT
SET BODY = CAST(REPLACE(CAST(BODY AS NVARCHAR(MAX)), 'Test' , 'prod') AS NTEXT)
WHERE BODY COLLATE Latin1_General_CI_AS LIKE '%Test%' COLLATE Latin1_General_CI_AS;
这个查询在做什么:
'Test'、'test'、'TEST' 更新为 'prod' -- 这是预期的。
'Test2'、'TestTest'、'Fastest' 更新为 'prod' - 我想避免这种行为。
请帮忙
我试过但没有成功的其他查询:
UPDATE BODYCONTENT
SET BODY = CAST(REPLACE(CAST(BODY AS NVARCHAR(MAX)), 'Test' , 'prod') AS NTEXT)
WHERE BODY COLLATE Latin1_General_CI_AS LIKE '%[^A-Za-z0-9]Test[^A-Za-z0-9]%' COLLATE Latin1_General_CI_AS;
当我使用以下查询为 'Test' 执行 select 时:
SELECT *
FROM dbo.BODYCONTENT
WHERE CONVERT(NVARCHAR(MAX), BODY) = N'Test';
它没有返回任何东西。但我可以使用以下查询获得结果:
SELECT BODY
FROM dbo.BODYCONTENT
WHERE BODY LIKE '%Test%';
SELECT BODY
FROM dbo.BODYCONTENT
WHERE BODY COLLATE Latin1_General_CI_AS like '%TEST%' COLLATE Latin1_General_CI_AS;
这是列值:
Test testtest Test1 Test TEST
预期结果:
prod testtest Test1 prod prod
当前结果:
prod prodprod prod1 prod prod
我的印象是 test
的所有不同版本都在同一行值内,这就是为什么您说建议的 like 'test'
不起作用。
基于此,下面的内容相当丑陋,但可以满足您的要求:
declare @t table(s ntext);
insert into @t values('Test testtest Test1 Test TEST');
select s as Original
,ltrim(rtrim(replace(
replace(
replace(N' ' + cast(s as nvarchar(max)) + N' ' -- Add a single space before and after value,
,' ','<>' -- then replace all spaces with any two characters.
)
,'>test<','>prod<' -- Use these two characters to identify single instances of 'test'
)
,'<>',' ' -- Then replace the delimiting characters with spaces and trim the value.
)
)
) as Updated
from @t;
输出:
+-------------------------------+-------------------------------+
| Original | Updated |
+-------------------------------+-------------------------------+
| Test testtest Test1 Test TEST | prod testtest Test1 prod prod |
+-------------------------------+-------------------------------+
使用 <>
代替空格是由于 SQL 服务器的默认行为忽略字符串比较中的尾随空格。这些可以是任意两个字符,但我觉得它们在美学上令人愉悦。