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 function : here
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 function : here
Adapted from @Shnugo's answer. This is closer to what you want. You just need to make certain you have a
dbo.numbers
table (they're REALLY useful to have).http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=627828307504174dcf3f61313ba384a8
And a slightly over the top way to meet your requirement that
TRANSLATE('abc', 'abc', 'bcd') => 'bcd')
.http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=9dbe7214ac4b5bb00060686cfaa879c2
A possible minor optimisation of the above (To reduce the number of REPLACE calls where possible)...
http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=8af6ae050dc8d425521ae911b70a7968
Or...
http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1451aa88780463b1e7cfe15dd0071194
Or...
http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=3079d4dd4289e8696072f6ee37be76ae
Better than a
WHILE
loop is - at least in my eyes - the quirky update wrapped in a function:You can maintain replace values in a table. You might add some grouping keys (e.g. for languag selection or topic focus) and pass this into the function as additional parameter:
--You cannot use the quirky update inlined, but you can wrap it within a scalar function:
--A table with test data
--Clean-Up
The result
I propose my translate function:
EDITED:
I'm feeling dumb - MatBailie correctly pointed out that my original solution was incorrect. I actually always thought that
TRANSLATE('abc', 'abc', 'bcd')
was supposed to return ddd but, after testing SQL Server 2017's TRANSLATE I see that 'bcd' would be the correct answer. You can see my original (incorrect version) by looking at this history of this post. Here's an updated solution that uses ngrams8k:Returns > bcd
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 withTRANSLATE
this would produce the errorThe 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
orRAISERROR
. This means that actually producing an error inside a function isn't possible. You could, however, set something up so thatNULL
is returned if the two lengths don't match, but (unfortunately) the error production cannot be performed inside the function itself.Any questions, please do ask.