Replace Character Without Using Looped REPLACE Function
Create a mapping between the old value and the new value in a table value constructor and use stuff to replace the character.
declare @T table(Value varchar(10));
insert into @T values
('Q234567888'),
('R264747848'),
('B264712481');
select stuff(T.Value, 1, 1, (
select V.NewValue
from (values('Q', 'I'),
('R', 'I'),
('B', 'U')) as V(OldValue, NewValue)
where V.OldValue = left(T.Value, 1)
))
from @T as T;
DECLARE @values TABLE
(
String CHAR(10)
)
INSERT INTO @values
values
('Q234567888'),
('R264747848'),
('B264712481');
SELECT
REPLACE(String,LEFT(String,1),ca.NewValue)
FROM @values
CROSS APPLY
(SELECT * FROM (values('Q', 'I'),
('R', 'I'),
('B', 'U'))as V(OldValue, NewValue)
WHERE v.OldValue = LEFT(string,1)
)ca
Here's another approach. While testing this, I ran @Mikael Eriksson's method and the CASE\REPLACE with 26 clauses, over a 3 million row test table and the CASE method was quickest hands down. That said, none were slow and the above and @Mikael's shook out evenly. Of course, YMMV.
Just to have this stated as an option since the O.P.'s version of SQL Server has not been mentioned, and the following is a valid approach starting with SQL Server 2017:
The TRANSLATE function is well suited for a direct 1-to-1 replacement of single characters:
DECLARE @TEST TABLE([Stuff] VARCHAR(10));
INSERT INTO @TEST ([Stuff]) VALUES
('Q234567888'),
('R264747848'),
('B264712481');
UPDATE tst
SET tst.[Stuff] =
STUFF(tst.[Stuff], 1, 1, (
TRANSLATE(LEFT(tst.[Stuff], 1), 'QRB', 'IIU')
))
FROM @TEST tst;
SELECT * FROM @TEST;
returns:
Stuff
----------
I234567888
I264747848
U264712481
P.S. Ignore SSMS (at least through v 17.5, I haven't yet tried 17.6) flagging TRANSLATE
as an invalid function. This behavior has been reported here.