I read that there is a function equivalent to the standard function TRANSLATE under DB2 under SQL Server 2017. But how to do under earlier versions?
For definition of fu
Thought I'd put my idea in as well. This avoids the dreaded WHILE loop, and, also, doesn't use a self referencing variable (which can get ugly).
Note the use of a Tally table, first, and then I use a Table Valued Function (rather than Scalar, which are slow) to do the work.
Note, that I have set it so that if you provide fewer arguments on the right hand side, that the character will be removed. So, if the parameter @FindChars had the value 'AB' and @ReplaceChars the value 'C', then 'A' would be replaced with 'C' and 'B' would be replaced with ''. I note that with TRANSLATE this would produce the error The second and third arguments of the TRANSLATE built-in function must contain an equal number of characters.
The problem, however, with a function is that you can't use things like THROW or RAISERROR. This means that actually producing an error inside a function isn't possible. You could, however, set something up so that NULL is returned if the two lengths don't match, but (unfortunately) the error production cannot be performed inside the function itself.
CREATE VIEW dbo.Tally WITH SCHEMABINDING
AS
WITH C1 AS (SELECT 1 AS I UNION ALL SELECT 1),
C2 AS (SELECT 1 AS I FROM C1 AS L CROSS JOIN C1 AS R),
C3 AS (SELECT 1 AS I FROM C2 AS L CROSS JOIN C2 AS R),
C4 AS (SELECT 1 AS I FROM C3 AS L CROSS JOIN C3 AS R),
C5 AS (SELECT 1 AS I FROM C4 AS L CROSS JOIN C4 AS R),
C6 AS (SELECT 1 AS I FROM C5 AS L CROSS JOIN C5 AS R),
RN AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM C6)
SELECT TOP (1000000) N
FROM RN
ORDER BY N;
GO
CREATE FUNCTION dbo.OwnTranslate (@String varchar(8000),@FindChars varchar(8000), @ReplaceChars varchar(8000))
RETURNS TABLE
AS RETURN (
WITH ToBeReplaced AS (
SELECT @String AS String,
FC.N,
SUBSTRING(@FindChars, FC.N,1) AS FC,
ISNULL(SUBSTRING(@ReplaceChars, RC.N,1),'') AS RC
FROM (SELECT TOP (LEN(@FindChars)) N FROM Tally) FC
OUTER APPLY (SELECT TOP (LEN(@ReplaceChars)) T.N FROM Tally T WHERE T.N = FC.N AND T.N <= LEN(@ReplaceChars)) RC),
Replacing AS (
SELECT N, REPLACE(String, FC, RC) AS ReplacedString
FROM ToBeReplaced
WHERE N = 1
UNION ALL
SELECT R.N + 1, REPLACE(ReplacedString, TBR.FC, TBR.RC) AS ReplacedString
FROM ToBeReplaced TBR
JOIN Replacing R ON TBR.N = R.N + 1)
SELECT TOP 1 ReplacedString
FROM Replacing
ORDER BY N DESC);
GO
WITH VTE AS (
SELECT *
FROM (VALUES ('This is a string to be Translated.')) V(S))
SELECT VTE.S, OT.ReplacedString
FROM VTE
CROSS APPLY dbo.OwnTranslate (VTE.S, 'Ts ', 'qz_') OT;
GO
--Clean up
DROP FUNCTION dbo.OwnTranslate;
DROP VIEW Tally;
Any questions, please do ask.