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