Започвайки със SQL Server 2017, вече можете да използвате T-SQL TRANSLATE()
функция за превод на един или повече символи в друг набор от знаци.
На пръв поглед може да си помислите, че TRANSLATE()
функцията прави точно същото нещо като REPLACE()
функция, но има значителни разлики между двете.
Дефиниции
Първо, нека разгледаме дефиницията на всяка функция:
REPLACE()
- Заменя всички срещания на определена низова стойност с друга низова стойност.
TRANSLATE()
- Връща низа, предоставен като първи аргумент, след като някои знаци, посочени във втория аргумент, са преведени в целеви набор от знаци.
Основната разлика е как всяка функция се справя с множество символи. REPLACE()
заменя един низ с друг низ. Следователно, ако низ съдържа няколко знака, всеки знак трябва да бъде в същия ред. TRANSLATE()
от друга страна, заменя всеки знак един по един, независимо от реда на тези знаци.
Пример – Същият резултат
Има случаи, когато и двете функции ще върнат един и същ резултат. Като това:
SELECT REPLACE('123', '123', '456') AS Replace, TRANSLATE('123', '123', '456') AS Translate;
Резултат:
Replace Translate ------- --------- 456 456
В този случай REPLACE()
връща 456
защото точният низ във втория аргумент съвпада с низ в първия аргумент (в този случай това беше целият низ).
TRANSLATE()
връща 456
защото всеки знак от втория аргумент присъства в първия аргумент.
Пример – различен резултат
Сега за пример, който демонстрира една от разликите между TRANSLATE()
и REPLACE()
:
SELECT REPLACE('123', '321', '456') AS Replace, TRANSLATE('123', '321', '456') AS Translate;
Резултат:
Replace Translate ------- --------- 123 654
В този случай REPLACE()
няма ефект (връща оригиналния низ), тъй като вторият аргумент не е точно съвпадение с първия аргумент (или подниз в него). Въпреки че вторият аргумент съдържа правилните знаци, те не са в същия ред като първия аргумент и следователно целият низ не съвпада.
TRANSLATE()
прави имат ефект, защото всеки знак от втория аргумент присъства в първия аргумент. Няма значение, че те са в различен ред, защото всеки знак се превежда един по един. SQL Server превежда първия знак, след това втория, след това третия и т.н.
Непоследователни низове
Подобно на предишния пример, можете също да получите различни резултати, когато първият аргумент съдържа знаците във втория аргумент, но те не са съседни:
SELECT REPLACE('1car23', '123', '456') AS Replace, TRANSLATE('1car23', '123', '456') AS Translate;
Резултат:
Replace Translate ------- --------- 1car23 4car56
Аргументи с различна дължина
Можете също да получите различни резултати между всяка функция, когато има несъответствия в броя на знаците в различните аргументи.
Ето пример, при който първият аргумент съдържа по-малко знаци от втория и третия аргумент:
SELECT REPLACE('123', '1234', '4567') AS Replace, TRANSLATE('123', '1234', '4567') AS Translate;
Резултат:
Replace Translate ------- --------- 123 456
В този случай REPLACE()
няма ефект, тъй като вторият аргумент съдържа повече знаци от първия аргумент. Следователно е невъзможно първият аргумент да съдържа втория аргумент.
TRANSLATE()
функция обаче има ефект в този случай. Това е така, защото вторият аргумент съдържа знаци, които са в първия аргумент. Няма значение, че вторият аргумент съдържа повече знаци от първия. Най-важното е, че третият аргумент съдържа същия брой знаци като втория.
Има и случаи, когато REPLACE()
работи перфектно, но TRANSLATE()
извежда грешка.
Пример:
SELECT REPLACE('1234', '123', '4567') AS Replace;
Резултат:
Replace ------- 45674
В този случай REPLACE()
работи според очакванията.
Въпреки това, ако предоставим същите аргументи на TRANSLATE()
, получаваме грешка:
SELECT TRANSLATE('1234', '123', '4567') AS Translate;
Резултат:
Error: The second and third arguments of the TRANSLATE built-in function must contain an equal number of characters.
Както се казва в съобщението за грешка, вторият и третият аргумент трябва да съдържат равен брой знаци.
Кога трябва да използвам REPLACE()?
Трябва да използвате REPLACE()
когато трябва да замените всички поява на конкретен низ, точно както е написан. Например промяна на името на някого с друго име.
Използване на TRANSLATE()
в такива случаи може да има катастрофални резултати:
SELECT REPLACE('Homer Simpson', 'Homer', 'Jason') AS Replace, TRANSLATE('Homer Simpson', 'Homer', 'Jason') AS Translate;
Резултат:
Replace Translate ------------- ------------- Jason Simpson Jason Sispsan
Кога трябва да използвам TRANSLATE()?
Както е показано в предишния пример, TRANSLATE()
функцията може да бъде полезна, ако трябва да замените всички срещания на всеки посочен символ, независимо от реда им в оригиналния низ.
Може да се използва и вместо REPLACE()
просто кода. Ето един пример (въз основа на пример на уебсайта на Microsoft):
SELECT REPLACE(REPLACE(REPLACE(REPLACE('2*[3+4]/{7-2}','[','('), ']', ')'), '{', '('), '}', ')') AS Replace, TRANSLATE('2*[3+4]/{7-2}', '[]{}', '()()') AS Translate;
Резултат:
Replace Translate ------------- ------------- 2*(3+4)/(7-2) 2*(3+4)/(7-2)