MYSQL- function parameter concat Chinese garbled

1. Background

In the past, I used to  postgresql write stored procedures/functions a lot. In this work process, data migration needs to be done to convert  MYSQL the data of some tables into some table data in the pgsql database

In the process of conversion, the following conversion SQL is required


if(@birthday is null) then
   @birthday='null';
else    
   @birthday=concat('\'',@birthday,"\'");
end if;

If birthday has no value, the 'null' string will be used, if there is a value, single quotes will be added

In addition to birthday, I also need to deal with

  • @local_real_name
  • @login_mobile
  • @login_name

Based on the  DRY (Don't repeat youself) principle, here should write afunction

2. The first version function

So, I referred to the mysql documentation and wrote a function

drop function if exists ifNullElseWithSigleQuotes;

--  -----------------------------------
create function ifNullElseWithSigleQuotes(
    in_string      varchar(255)
)
returns varchar(255)
begin
    declare resultValue varchar(255);

    if(in_string is null) then
       set resultValue='null';
    else    
       set resultValue=concat('\'',in_string,'\'');
    end if;

    return(resultValue);
end

It's very simple, look at it with the naked eye, there is nothing wrong with it

Execute, prompt:

ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled

(you *might* want to use the less safe log_bin_trust_function_creators variable)

Check out the help documentation


[NOT] DETERMINISTIC:这个是用于binlog和主从复制等!DETERMINISTIC是确定的,
意思就是写入binlog的时候,写入的是一个指定的常量;如unix_timestamp()获取到的值是1,可能写入binlog的时候,unix_timestamp()获取到的时间戳却成了3了,这个时候会出现数据不一致问题,所以引入了DETERMINISTIC!这是binlog安全的一种机制!一般情况下,NOT DETERMINISTIC不允许使用,会报如下错误:
Error CODE : 1418
This FUNCTION has NONE of DETERMINISTIC, NO SQL, OR READS SQL DATA IN its declaration AND BINARY logging IS enabled (you *might* want TO USE the LESS safe log_bin_trust_function_creators variable)

可以从报错内容里面发现,设置log_bin_trust_function_creators函数就可以使用NOT DETERMINISTIC,但是二进制安全性极差!

CONTAINS SQL表示子程序不包含读或写数据的语句;

NO SQL表示子程序不包含SQL语句。

READS SQL DATA表示子程序包含读数据的语句,但不包含写数据的语句。

MODIFIES SQL DATA表示子程序包含写数据的语句。

如果这些特征没有明确给定,默认的是CONTAINS SQL。

I have no sql statement in this function, so I added it no sql

create function ifNullElseWithSigleQuotes(
    in_string      varchar(255)
)
returns varchar(255)
no sql

begin
    declare resultValue varchar(255);

    if(in_string is null) then
       set resultValue='null';
    else    
       set resultValue=concat('\'',in_string,'\'');
    end if;

    return(resultValue);

end

But still can't execute

Final solution:  find our DBA and adjust the mysql bin-log parameters

Reference:  http://www.educity.cn/wenda/402115.html

3. Execute

After solving the function creation exception, we created the function successfully,

3.1 test null

select ifNullElseWithSigleQuotes(null);

result:

ifNullElseWithSigleQuotes(null) |
--------------------------------|
null                            |

no problem

3.2 test mobile

select ifNullElseWithSigleQuotes('15001841110');

result:

ifNullElseWithSigleQuotes('15001841110') |
-----------------------------------------|
'15001841110'                            |

no problem

3.3 test local_real_name

select ifNullElseWithSigleQuotes('程序员鼓励师');

result:

SQL 错误 [1366] [HY000]: Incorrect string value: '\xE7\xA8\x8B\xE5\xBA\x8F...' for column 'in_string' at row 1

  java.sql.SQLException: Incorrect string value: '\xE7\xA8\x8B\xE5\xBA\x8F...' for column 'in_string' at row 1

Hey, what's the situation, is it  程序员鼓励师 too beautiful to cause the function to fail to execute?

4. Find solutions

The first feeling is garbled code, is it because the encoding is not set,

4.1 Find documentation, plus charset utf8

drop function if exists ifNullElseWithSigleQuotes;

--  -------------------------------------
create function ifNullElseWithSigleQuotes(
    in_string      varchar(255) charset utf8
)
returns varchar(255) charset utf8
no sql

begin
    declare resultValue varchar(255);

    if(in_string is null) then
       set resultValue='null';
    else    
       set resultValue=concat('\'',in_string,'\'');
    end if;

    return(resultValue);

end

implement:

select ifNullElseWithSigleQuotes('程序员鼓励师');

result:

SQL 错误 [1366] [HY000]: Incorrect string value: '\xE7\xA8\x8B\xE5\xBA\x8F...' for column 'resultValue' at row 1

java.sql.SQLException: Incorrect string value: '\xE7\xA8\x8B\xE5\xBA\x8F...' for column 'resultValue' at row 1

The sound of the waves remains, the problem remains

4.2 Consulted with our DBA

DBA enlightened me with an idea, is there a problem with the function called internally, so I modified a version

drop function if exists ifNullElseWithSigleQuotes;

--  -----------------------------------
create function ifNullElseWithSigleQuotes(
    in_string      varchar(255) charset utf8
)
returns varchar(255) charset utf8
no sql

begin    
    return('111');    
end

implement:

select ifNullElseWithSigleQuotes('程序员鼓励师');

result:

ifNullElseWithSigleQuotes('程序员鼓励师') |
------------------------------------|
111                                 |

Hey, isn't it amazing? It seems that there is no problem with passing parameters and returning part of the code

4.3 Problems with concat?

Then there is  concat a problem? Look for information

under google mysql concat Incorrect string value

Found some information, but most of the information says

concat(str1,str2)

当concat结果集出现乱码时,大都是由于连接的字段类型不同导致,如concat中的字段参数一个是varchar类型,一个是int类型或doule类型,就会出现乱码。

解决方法:利用mysql的字符串转换函数CONVERT将参数格式化为char类型就可以了。

举例: concat('数量:',CONVERT(int1,char),CONVERT(int2,char),'金额:',CONVERT(double1,char),CONVERT(double2,char))

but my code

select concat('\'','程序员鼓励师','\'');

result :

concat('\'','程序员鼓励师','\'') |
---------------------------|
'程序员鼓励师'                   |

no problem

4.4 The willows are dark and the flowers are bright

When I'm at a loss, I see

 declare resultValue varchar(255);

I added him too charset

Code :

drop function if exists ifNullElseWithSigleQuotes;

--  ----------------------------
create function ifNullElseWithSigleQuotes(
    in_string      varchar(255) charset utf8
)
returns varchar(255) charset utf8
no sql

begin
    declare resultValue varchar(255) charset utf8;

    if(in_string is null) then
       set resultValue='null';
    else    
       set resultValue=concat('\'',in_string,'\'');
    end if;

    return(resultValue);

end

implement:

select ifNullElseWithSigleQuotes('程序员鼓励师');

result :

ifNullElseWithSigleQuotes('程序员鼓励师') |
------------------------------------|
'程序员鼓励师'                            |

5. Summary

  • When you encounter a problem, you need to find a possible solution (find someone to ask, find information)
  • Try more, summarize more
  • I spent 4 hours on this small function, I think it is necessary to make a summary, I hope if you encounter the same problem, after reading my article, you can get it done in 4 minutes
  • mysql It's not easy to say I love you

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326305763&siteId=291194637