Począwszy od SQL Server 2017, możesz teraz używać T-SQL TRANSLATE()
funkcja tłumaczenia jednego lub więcej znaków na inny zestaw znaków.
Na pierwszy rzut oka możesz pomyśleć, że TRANSLATE()
funkcja robi dokładnie to samo, co REPLACE()
funkcji, ale istnieją między nimi znaczące różnice.
Definicje
Najpierw spójrzmy na definicję każdej funkcji:
REPLACE()
- Zamienia wszystkie wystąpienia określonej wartości ciągu na inną wartość ciągu.
TRANSLATE()
- Zwraca ciąg dostarczony jako pierwszy argument po tym, jak niektóre znaki określone w drugim argumencie zostaną przetłumaczone na docelowy zestaw znaków.
Główna różnica polega na tym, jak każda funkcja radzi sobie z wieloma znakami. REPLACE()
zastępuje jeden ciąg innym ciągiem. Dlatego jeśli ciąg zawiera wiele znaków, każdy znak musi być w tej samej kolejności. TRANSLATE()
z drugiej strony, zastępuje każdy znak jeden po drugim, niezależnie od kolejności tych znaków.
Przykład – ten sam wynik
W niektórych przypadkach obie funkcje zwrócą ten sam wynik. Tak:
SELECT REPLACE('123', '123', '456') AS Replace, TRANSLATE('123', '123', '456') AS Translate;
Wynik:
Replace Translate ------- --------- 456 456
W tym przypadku REPLACE()
zwraca 456
ponieważ dokładny ciąg w drugim argumencie pasował do ciągu w pierwszym argumencie (w tym przypadku był to cały ciąg).
TRANSLATE()
zwraca 456
ponieważ każdy znak w drugim argumencie występuje w pierwszym argumencie.
Przykład – inny wynik
A teraz przykład, który pokazuje jedną z różnic między TRANSLATE()
i REPLACE()
:
SELECT REPLACE('123', '321', '456') AS Replace, TRANSLATE('123', '321', '456') AS Translate;
Wynik:
Replace Translate ------- --------- 123 654
W tym przypadku REPLACE()
nie ma żadnego efektu (zwraca oryginalny ciąg), ponieważ drugi argument nie jest dokładnym dopasowaniem do pierwszego argumentu (lub jego podciągu). Mimo że drugi argument zawiera poprawne znaki, nie są one w tej samej kolejności co pierwszy argument, a zatem cały ciąg nie pasuje.
TRANSLATE()
tak mają skutek, ponieważ każdy znak w drugim argumencie występuje w pierwszym argumencie. Nie ma znaczenia, że są w innej kolejności, ponieważ każdy znak jest tłumaczony jeden po drugim. SQL Server tłumaczy pierwszy znak, potem drugi, trzeci i tak dalej.
ciągi nieciągłe
Podobnie jak w poprzednim przykładzie, możesz również uzyskać różne wyniki, gdy pierwszy argument zawiera znaki z drugiego argumentu, ale nie są one ciągłe:
SELECT REPLACE('1car23', '123', '456') AS Replace, TRANSLATE('1car23', '123', '456') AS Translate;
Wynik:
Replace Translate ------- --------- 1car23 4car56
Argumenty o różnej długości
Możesz również uzyskać różne wyniki dla każdej funkcji, gdy występują rozbieżności w liczbie znaków w różnych argumentach.
Oto przykład, w którym pierwszy argument zawiera mniej znaków niż drugi i trzeci argument:
SELECT REPLACE('123', '1234', '4567') AS Replace, TRANSLATE('123', '1234', '4567') AS Translate;
Wynik:
Replace Translate ------- --------- 123 456
W tym przypadku REPLACE()
nie ma żadnego efektu, ponieważ drugi argument zawiera więcej znaków niż pierwszy argument. Dlatego niemożliwe jest, aby pierwszy argument zawierał drugi argument.
TRANSLATE()
jednak funkcja ma w tym przypadku wpływ. Dzieje się tak, ponieważ drugi argument zawiera znaki znajdujące się w pierwszym argumencie. Nie ma znaczenia, że drugi argument zawiera więcej znaków niż pierwszy. Najważniejszą rzeczą jest to, że trzeci argument zawiera taką samą liczbę znaków jak drugi.
Istnieją również przypadki, gdy REPLACE()
działa doskonale, ale TRANSLATE()
zgłasza błąd.
Przykład:
SELECT REPLACE('1234', '123', '4567') AS Replace;
Wynik:
Replace ------- 45674
W tym przypadku REPLACE()
działa zgodnie z oczekiwaniami.
Jeśli jednak dostarczymy te same argumenty do TRANSLATE()
, pojawia się błąd:
SELECT TRANSLATE('1234', '123', '4567') AS Translate;
Wynik:
Error: The second and third arguments of the TRANSLATE built-in function must contain an equal number of characters.
Jak mówi komunikat o błędzie, drugi i trzeci argument muszą zawierać taką samą liczbę znaków.
Kiedy powinienem używać REPLACE()?
Powinieneś użyć REPLACE()
kiedy musisz zamienić wszystkie wystąpienia określonego ciągu, dokładnie tak, jak jest napisane. Na przykład zmiana czyjegoś imienia na inne.
Używanie TRANSLATE()
w takich przypadkach może mieć katastrofalne skutki:
SELECT REPLACE('Homer Simpson', 'Homer', 'Jason') AS Replace, TRANSLATE('Homer Simpson', 'Homer', 'Jason') AS Translate;
Wynik:
Replace Translate ------------- ------------- Jason Simpson Jason Sispsan
Kiedy powinienem używać TRANSLATE()?
Jak pokazano w poprzednim przykładzie, TRANSLATE()
funkcja może być użyteczna, jeśli chcesz zastąpić wszystkie wystąpienia każdego określonego znaku, niezależnie od ich kolejności w oryginalnym ciągu.
Może być również użyty zamiast REPLACE()
po prostu kod. Oto przykład (na podstawie przykładu ze strony Microsoft):
SELECT REPLACE(REPLACE(REPLACE(REPLACE('2*[3+4]/{7-2}','[','('), ']', ')'), '{', '('), '}', ')') AS Replace, TRANSLATE('2*[3+4]/{7-2}', '[]{}', '()()') AS Translate;
Wynik:
Replace Translate ------------- ------------- 2*(3+4)/(7-2) 2*(3+4)/(7-2)