MODIFIÉ :
Je me sens stupide - MatBailie a correctement souligné que ma solution d'origine était incorrecte. En fait, j'ai toujours pensé que TRANSLATE('abc', 'abc', 'bcd')
était censé renvoyer ddd mais, après avoir testé TRANSLATE de SQL Server 2017, je vois que 'bcd' serait la bonne réponse. Vous pouvez voir mon original (version incorrecte) en regardant cet historique de ce post. Voici une solution mise à jour qui utilise ngrams8k
:
DECLARE
@string varchar(8000) = 'abc',
@fromChar varchar(100) = 'abc', -- note: no mutation
@toChar varchar(100) = 'bcd';
SELECT newString =
(
SELECT CASE WHEN x>z THEN '' WHEN x>0 THEN s ELSE t END+''
FROM dbo.ngrams8k(@string,1) ng
CROSS APPLY (VALUES (charindex(ng.token,@fromChar),len(@toChar),ng.token)) x(x,z,t)
CROSS APPLY (VALUES (ng.position, substring(@toChar,x.x,1))) xx(p,s)
ORDER BY xx.p
FOR XML PATH(''), TYPE
).value('(text())[1]', 'varchar(8000)');
Retours> bdc