Firebird Создайте функцию TRANSLATE как в Oracle

Я пытаюсь создать функцию с той же функциональностью, что и функция TRANSLATE в Oracle, я создал функцию в Oracle, и она работает хорошо, но у меня возникла проблема, когда я пытаюсь переписать этот код в Firebird. Я получаю сообщение об ошибке, что «вычисление выражения не поддерживается». Почему?

CREATE FUNCTION TRANSLATEE
(text varchar(10000),
toReplace varchar(10000),
replacePattern varchar(10000)
)
RETURNs VARCHAR(100)
aS

declare variable cut varchar(100);
declare variable i integer;
declare variable position1  varchar(100);
declare variable resultat  varchar(100);
declare variable letter  varchar(100);
declare variable lenght integer;
BEGIN
i = 1;
resultat ='';
lenght =  char_length(:text);
while(i<lenght) do
begin
    cut = substring(:text from i for 1);
    position1 = position(:toReplace , cut);
      if (position(:toReplace , cut) >0) then
      begin
        letter = substring(:replacePattern from position1 for 1);
        resultat = resultat||''||letter;
        end
      else 
      begin
       resultat = resultat ||''|| cut;
      end
  i = i+1;
end
  RETURN resultat;
END;

person Tomasz Dębski    schedule 08.04.2015    source источник
comment
Вы используете Firebird 3 (бета)? Более ранние версии Firebird не имеют процедурных функций (только функции, определенные во внешних библиотеках и хранимых процедурах).   -  person Mark Rotteveel    schedule 11.04.2015


Ответы (2)


Основная проблема заключается в том, что вы объявили position1 как VARCHAR(100), а не как INTEGER. Это приводит к бесполезной ошибке, поскольку нет версии подстроки, которая принимает параметр varchar (и в этом контексте преобразование из varchar в целое число не поддерживается).

Рабочая (или, по крайней мере, компилируемая) версия вашей функции:

CREATE OR ALTER FUNCTION TRANSLATE_func
   (text varchar(10000), 
    toReplace varchar(10000), 
    replacePattern varchar(10000))
RETURNS VARCHAR(100)
AS
   declare variable resultat varchar(100);
   declare variable cut varchar(100);
   declare variable i integer;
   declare variable position1  integer;
   declare variable letter  varchar(100);
   declare variable lenght integer;
BEGIN
   i = 1;
   resultat ='';
   lenght =  char_length(text);
   while(i <= lenght) do
   begin
       cut = substring(text from i for 1);
       position1 = position(cut, toReplace);
       if (position1 > 0) then
       begin
           letter = substring(replacePattern from position1 for 1);
           resultat = resultat||''||letter;
       end
       else 
       begin
           resultat = resultat ||''|| cut;
       end
       i = i+1;
   end
   return resultat;
END
person Mark Rotteveel    schedule 11.04.2015

Для Жар-птицы 3

SET TERM ^ ;

create function translator (
    inp varchar(10000),
    pat varchar(1000),
    rep varchar(1000))
returns varchar(10000)
as
    declare variable tex varchar(10000);
    declare variable inp_idx integer = 1;
    declare variable cha char(1);
    declare variable pos integer;
begin
  tex = '';
  while (inp_idx <= char_length(inp)) do
  begin
    cha = substring(inp from inp_idx for 1);
    pos = position(cha, pat);
    if (pos > 0) then
      cha = substring(rep from pos for 1);
    tex = tex || cha;
    inp_idx = inp_idx + 1;
  end
  return tex;
end^

SET TERM ; ^

Тест

select translator('džiná lasaí ireo dana kýrne číraž', 'ážíýč', 'AZIYC')
  from rdb$database;

Результат

dZinA lasaI ireo dana kYrne CIraZ
person Atiris    schedule 03.12.2019