Počínaje SQL Server 2017 můžete nyní používat T-SQL TRANSLATE()
funkce pro překlad jednoho nebo více znaků do jiné sady znaků.
Na první pohled si můžete myslet, že TRANSLATE()
Funkce dělá přesně to samé jako REPLACE()
funkce, ale mezi těmito dvěma jsou značné rozdíly.
Definice
Nejprve se podívejme na definici každé funkce:
REPLACE()
- Nahradí všechny výskyty zadané řetězcové hodnoty jinou řetězcovou hodnotou.
TRANSLATE()
- Vrátí řetězec zadaný jako první argument poté, co jsou některé znaky zadané ve druhém argumentu přeloženy do cílové sady znaků.
Hlavním rozdílem je, jak každá funkce pracuje s více znaky. REPLACE()
nahradí jeden řetězec jiným řetězcem. Pokud tedy řetězec obsahuje více znaků, musí být každý znak ve stejném pořadí. TRANSLATE()
na druhé straně nahrazuje každý znak jeden po druhém, bez ohledu na pořadí těchto znaků.
Příklad – stejný výsledek
Existují případy, kdy obě funkce vrátí stejný výsledek. Takhle:
SELECT REPLACE('123', '123', '456') AS Replace, TRANSLATE('123', '123', '456') AS Translate;
Výsledek:
Replace Translate ------- --------- 456 456
V tomto případě REPLACE()
vrátí 456
protože přesný řetězec ve druhém argumentu se shodoval s řetězcem v prvním argumentu (v tomto případě to byl celý řetězec).
TRANSLATE()
vrátí 456
protože každý znak ve druhém argumentu je přítomen v prvním argumentu.
Příklad – jiný výsledek
Nyní příklad, který ukazuje jeden z rozdílů mezi TRANSLATE()
a REPLACE()
:
SELECT REPLACE('123', '321', '456') AS Replace, TRANSLATE('123', '321', '456') AS Translate;
Výsledek:
Replace Translate ------- --------- 123 654
V tomto případě REPLACE()
nemá žádný účinek (vrací původní řetězec), protože druhý argument se přesně neshoduje s prvním argumentem (nebo podřetězcem v něm). I když druhý argument obsahuje správné znaky, nejsou ve stejném pořadí jako první argument, a proto se celý řetězec neshoduje.
TRANSLATE()
dělá mít účinek, protože každý znak ve druhém argumentu je přítomen v prvním argumentu. Nezáleží na tom, že jsou v jiném pořadí, protože každá postava je překládána jedna po druhé. SQL Server přeloží první znak, pak druhý, pak třetí a tak dále.
Nesouvislé řetězce
Podobně jako v předchozím příkladu můžete také získat odlišné výsledky, když první argument obsahuje znaky z druhého argumentu, ale ty nejsou souvislé:
SELECT REPLACE('1car23', '123', '456') AS Replace, TRANSLATE('1car23', '123', '456') AS Translate;
Výsledek:
Replace Translate ------- --------- 1car23 4car56
Argumenty různé délky
Můžete také získat různé výsledky mezi každou funkcí, kdykoli existují nesrovnalosti v počtu znaků v různých argumentech.
Zde je příklad, kdy první argument obsahuje méně znaků než druhý a třetí argument:
SELECT REPLACE('123', '1234', '4567') AS Replace, TRANSLATE('123', '1234', '4567') AS Translate;
Výsledek:
Replace Translate ------- --------- 123 456
V tomto případě REPLACE()
nemá žádný účinek, protože druhý argument obsahuje více znaků než první argument. Proto je nemožné, aby první argument obsahoval druhý argument.
TRANSLATE()
funkce však má v tomto případě vliv. Důvodem je, že druhý argument obsahuje znaky, které jsou v prvním argumentu. Nezáleží na tom, že druhý argument obsahuje více znaků než první. Nejdůležitější je, že třetí argument obsahuje stejný počet znaků jako druhý.
Existují také případy, kdy REPLACE()
funguje perfektně, ale TRANSLATE()
vyvolá chybu.
Příklad:
SELECT REPLACE('1234', '123', '4567') AS Replace;
Výsledek:
Replace ------- 45674
V tomto případě REPLACE()
funguje podle očekávání.
Pokud však poskytneme stejné argumenty pro TRANSLATE()
, dostaneme chybu:
SELECT TRANSLATE('1234', '123', '4567') AS Translate;
Výsledek:
Error: The second and third arguments of the TRANSLATE built-in function must contain an equal number of characters.
Jak uvádí chybová zpráva, druhý a třetí argument musí obsahovat stejný počet znaků.
Kdy mám použít REPLACE()?
Měli byste použít REPLACE()
když potřebujete nahradit všechny výskyty konkrétního řetězce, přesně tak, jak je napsán. Například změna něčího jména na jiné.
Pomocí TRANSLATE()
v takových případech může mít katastrofální následky:
SELECT REPLACE('Homer Simpson', 'Homer', 'Jason') AS Replace, TRANSLATE('Homer Simpson', 'Homer', 'Jason') AS Translate;
Výsledek:
Replace Translate ------------- ------------- Jason Simpson Jason Sispsan
Kdy mám použít TRANSLATE()?
Jak je ukázáno v předchozím příkladu, TRANSLATE()
Funkce může být užitečná, pokud potřebujete nahradit všechny výskyty každého zadaného znaku, bez ohledu na jejich pořadí v původním řetězci.
Lze jej také použít místo REPLACE()
jednoduše kód. Zde je příklad (založený na příkladu na webu společnosti Microsoft):
SELECT REPLACE(REPLACE(REPLACE(REPLACE('2*[3+4]/{7-2}','[','('), ']', ')'), '{', '('), '}', ')') AS Replace, TRANSLATE('2*[3+4]/{7-2}', '[]{}', '()()') AS Translate;
Výsledek:
Replace Translate ------------- ------------- 2*(3+4)/(7-2) 2*(3+4)/(7-2)