【问题标题】:Is there a MySQL equivalent for Translate() in OracleOracle 中的 Translate() 是否有 MySQL 等价物
【发布时间】:2015-09-12 23:47:51
【问题描述】:

我正在从 Hibernate 中的 MySQL 表中检索一些密码值,并将其替换为 MySQL 中的其他字符串。我知道 Oracle 中有 translate() 来进行替换,但我在 MySQL 中没有找到任何相同的东西。 除了 MySQL 中的 Replace() 或任何可用于相同目的的库之外,还有其他解决方案吗?

【问题讨论】:

  • 感谢 Vao。但它不起作用。如果在 Oracle 中,我需要的是如下内容: translate(Password,'filqsnmpktyzJIjuv','abcdefghijklm') 我想知道在 MySQL 中这个 TRANSLATE 的替代方法是什么!

标签: mysql oracle hibernate


【解决方案1】:
delimiter //
drop function if exists my_translate_fx //
create function my_translate_fx (p_str varchar(1024), p_ori varchar(1024), p_rep varchar(1024))
    -- Replace characters p_ori with corresponding characters p_rep in string p_str
returns varchar(1024)
begin
  declare l_ori     varchar(1024)   default ifnull(p_ori,'') ;
  declare l_rep     varchar(1024)   default ifnull(p_rep,'') ;
  declare l_len_ori int unsigned    default ifnull(length(p_ori),0) ;
  declare l_len_rep int unsigned    default ifnull(length(p_rep),0) ;
  declare l_res     varchar(1024)   default p_str ;
  declare l_last_rep_chr varchar(6) default '' ;
  declare l_pos_ori int unsigned    default 1;

  -- No change if no original char to replace
  if l_len_ori < 1 then
    return l_res ;
  end if;

  -- Replacement string p_rep to be same size as p_ori, when p_rep is not null
  -- Complete replacement string repeating the last char in p_rep, eg. ' '
  if l_len_rep > 0 then
    set l_last_rep_chr := substr( l_rep ,l_len_rep,1) ;
    while l_len_rep < l_len_ori do
      set l_len_rep := l_len_rep + 1 ;
      set l_rep := concat( l_rep, l_last_rep_chr );
    end while ;
  end if;

  while l_pos_ori <= l_len_ori do
    set l_res = replace(l_res, substr(l_ori, l_pos_ori, 1), substr(l_rep, l_pos_ori, 1) );
    set l_pos_ori = l_pos_ori + 1;
  end while;

  return l_res ;
end;
//
delimiter ;

select my_translate_fx( '123123','23',' ');
-- select my_translate_fx( '123123','23','xy');
-- select my_translate_fx( '123123','1',' x');
-- select my_translate_fx( '123123','23','');
-- select my_translate_fx( '123123','','z');

【讨论】:

    【解决方案2】:

    我稍微调整了 Flavio 的答案,以下功能似乎对我有用。

    CREATE FUNCTION `translate` (
        tar VARCHAR (255),
        ori VARCHAR (255),
        rpl VARCHAR (255)
    ) RETURNS VARCHAR (255) CHARSET utf8mb4 DETERMINISTIC BEGIN
    
        DECLARE i INT UNSIGNED DEFAULT 0;
        DECLARE cur_char CHAR (1);
        DECLARE ori_idx INT UNSIGNED;
        DECLARE result VARCHAR (255);
    
        SET result = '';
    
        WHILE i <= length(tar) DO
            SET cur_char = mid(tar, i, 1);
            SET ori_idx = INSTR(ori, cur_char);
            SET result = concat(
                result,
                REPLACE(
                    cur_char,
                    mid(ori, ori_idx, 1),
                    mid(rpl, ori_idx, 1)
            ));
            SET i = i + 1;
        END WHILE;
        RETURN result;
    END
    

    使用以下示例进行测试:

    mysql> SET @map_src = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SET @map_des = 'nrgzujmaqbetylxwkdohpfvcisNRGZUJMAQBETYLXWKDOHPFVCIS2014587639';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT translate('https://456.HELLO.world', @map_src, @map_des) as f1;
    +-------------------------+
    | f1                      |
    +-------------------------+
    | ahhwo://458.AUTTX.vxdtz |
    +-------------------------+
    1 row in set (0.00 sec)
    

    【讨论】:

      【解决方案3】:

      你可以像这样创建一个:

      CREATE FUNCTION `translate`(subject varchar(255), what varchar(255), replace_to varchar(255)) RETURNS varchar(255)
      begin
       declare c int unsigned default 0;
       declare result varchar(255);
      
       set result = subject;
      
       while c <= length(subject) do
        set result = replace(result, mid(what, c, 1), mid(replace_to, c, 1) );
        set c=c+1;   
       end while;
      
       return result; 
      end
      

      然后使用:

      mysql> select translate('(123) 1234-1234', '( )-','.,.,');
      +---------------------------------------------+
      | translate('(123) 1234-1234', '( )-','.,.,') |
      +---------------------------------------------+
      | .123.,1234,1234                             |
      +---------------------------------------------+
      1 row in set (0.00 sec)
      

      【讨论】:

      • 这个解决方案似乎有问题,为什么主循环在subject上进行迭代,但是whatreplace中使用了迭代器c
      【解决方案4】:

      到目前为止,MySQL 中还没有与 Oracle 的 TRANSLATE() 函数等效的功能。但是,您可以通过使用嵌套的 REPLACE() 函数来获得所需的结果。

      添加示例 -
      Oracle 查询 -
      SELECT TRANSLATE('Vikas#Bharti-Infy', '#-', '_.') FROM dual;

      Vikas_Bharti.Infy

      等效的 MySQL 查询 将是 -
      SELECT REPLACE(REPLACE('Vikas#Bharti-Infy', '#', '_'),'-','.');

      Vikas_Bharti.Infy

      【讨论】:

        猜你喜欢
        • 2011-07-14
        • 1970-01-01
        • 2011-02-13
        • 2010-12-06
        • 2010-10-07
        • 1970-01-01
        • 2013-09-30
        • 2012-10-03
        相关资源
        最近更新 更多