1. 背景
以前使用 postgresql
写存储过程/function 比较多, 这次工作过程中,需要做数据迁移, 将 MYSQL
某些表的数据转成 pgsql数据库中某些表数据
在转换的过程中,需要有以下的转换SQL
if(@birthday is null) then
@birthday='null';
else
@birthday=concat('\'',@birthday,"\'");
end if;
如果 birthday 没有值,那么将使用 'null' 字符串,如果有值,将添加单引号
除了birthday ,我还需要处理
- @local_real_name
- @login_mobile
- @login_name
基于 DRY (Don't repeat youself)
原则, 这里应该写个function
2. 第一版function
于是乎,我就参考了mysql 文档,写了个 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
很简洁吧,肉眼看看,没毛病
执行下, 提示:
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)
看了下帮助文档
[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。
我这个function 里面没有sql语句, 那么加上了 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
但是依然执行不了
最终解决方案: 找到我们的DBA,将mysql bin-log 参数调整了
参考: http://www.educity.cn/wenda/402115.html
3. 执行
解决了 function创建异常之后, 我们创建function成功,
3.1 test null
select ifNullElseWithSigleQuotes(null);
结果:
ifNullElseWithSigleQuotes(null) |
--------------------------------|
null |
没毛病
3.2 test mobile
select ifNullElseWithSigleQuotes('15001841110');
结果:
ifNullElseWithSigleQuotes('15001841110') |
-----------------------------------------|
'15001841110' |
也没毛病
3.3 test local_real_name
select ifNullElseWithSigleQuotes('程序员鼓励师');
结果:
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
咦,什么情况, 难道是 程序员鼓励师
太美,导致 function 不能执行?
4. 寻找解决方案
第一感觉是乱码, 是不是哪里的编码没有设置,
4.1 找到文档, 加上 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
执行:
select ifNullElseWithSigleQuotes('程序员鼓励师');
结果:
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
涛声依旧, 问题依旧
4.2 咨询了下 我们的DBA
DBA启迪了我一个思路, 是不是内部调用的函数有问题, 那么 我修改了一版
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
执行:
select ifNullElseWithSigleQuotes('程序员鼓励师');
结果:
ifNullElseWithSigleQuotes('程序员鼓励师') |
------------------------------------|
111 |
嘿, 是不是很神奇? 看来传参和 return 部分代码没有问题
4.3 concat 的问题?
那就是 concat
有问题了? 找找资料
google 下 mysql concat Incorrect string value
找到了些资料, 但是大部分资料都是说
concat(str1,str2)
当concat结果集出现乱码时,大都是由于连接的字段类型不同导致,如concat中的字段参数一个是varchar类型,一个是int类型或doule类型,就会出现乱码。
解决方法:利用mysql的字符串转换函数CONVERT将参数格式化为char类型就可以了。
举例: concat('数量:',CONVERT(int1,char),CONVERT(int2,char),'金额:',CONVERT(double1,char),CONVERT(double2,char))
但是我的代码
select concat('\'','程序员鼓励师','\'');
结果 :
concat('\'','程序员鼓励师','\'') |
---------------------------|
'程序员鼓励师' |
没毛病啊
4.4 柳暗花明
在我没辙的时候, 我看到
declare resultValue varchar(255);
我给他也加了 charset
代码 :
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
执行:
select ifNullElseWithSigleQuotes('程序员鼓励师');
结果 :
ifNullElseWithSigleQuotes('程序员鼓励师') |
------------------------------------|
'程序员鼓励师' |
5.总结
- 遇到问题要寻找可能解决的办法(找人问,找资料)
- 多尝试,多总结
- 这个小function 我花费了4个小时, 我觉得有必要做个总结,希望如果遇到相同的问题,看了我的这个文章,4分钟就搞定了
- mysql 想说爱你不容易
相关推荐
资源分类:Python库 所属语言:Python 资源全名:flake8-no-implicit-concat-0.2.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
前端开源库-gulp-concat-cssgulp concat css,连接css文件,重新设置URL和inline@import
前端开源库-fuse-concat-with-sourcemaps将concat与sourcemaps融合,用自定义分隔符连接文件内容并生成源映射
前端开源库-stream-concat流concat,简单高效的节点流连接。
前端开源库-source-map-concat源映射concat,将文件与源映射连接起来。
gem 'fluent-plugin-concat' 然后执行: $ bundle 或将其自己安装为: $ gem install fluent-plugin-concat 配置 例子 @type concat key loga #separator "\n" n_lines 10 #multiline_start_regexp /^...
前端开源库-gulp-concat-sourcemapGulp Concat源映射,连接文件并生成源映射文件
主要介绍了nginx中使用nginx-http-concat模块合并静态资源文件,用以加速网站的CSS、JS等静态资源载入速度,需要的朋友可以参考下
前端开源库-broccoli-concat-analyser花椰菜浓缩物分析仪,
前端开源库-fuse-concat-with-sourcemaps.zip
-json-CONCAT 结合几个JSON文件与Gulp gulp-json-concat是一个分支,具有一些新选项。 安装 $ npm install --save-dev gulp-json-concat 用法 您可以组合子文件夹中的json文件。 生成的json将删除这些文件夹的名称...
grunt-cmd-concat 连接 cmd 文件。入门这个插件需要 Grunt ~0.4.0 如果您以前没有使用过 ,请务必查看指南,因为它解释了如何创建以及安装和使用 Grunt 插件。 熟悉该过程后,您可以使用以下命令安装此插件: npm ...
grunt-scantree-concat 连接scantree输出中JavaScript文件什么请参阅了解该过程的工作方式。 在以这种方式设置的项目中, grunt-scantree-concat将scantree输出中列出的文件连接到单个文件中。如何咕unt声这个插件...
grunt-contrib-concat v1.0.1 连接文件。 入门 如果您以前从未使用过 ,请务必查看《指南》,因为它说明了如何创建以及安装和使用Grunt插件。 熟悉该过程后,可以使用以下命令安装此插件: npm install grunt-...
task ( 'template' , function ( ) { gulp . src ( 'client/templates/**/*.jade' ) . pipe ( jade ( { client : true , compileDebug : false } } ) ) . pipe ( treeConcat ( { output : 'template.j
吞咽打字本Concat 一个gulp插件,允许串联TYPO3的TypoScript文件。 这使您可以.ts使用.ts文件进行开发,但最后使用已编译的单个文件进行开发。安装npm install --save-dev gulp-typoscript-concat用法Gulp文件const ...
import concat from 'stream-concat-promise' concat ( process . stdin ) . then ( console . log ) 混合流/承诺 这是一个模仿 concat-stream-promise API 的版本。 它无法将流错误传递给承诺,因此您仍然需要进行...
nginx-http-concat 概述 WP.com插件可将单个脚本CSS和Javascript连接成一个脚本。 安装与配置 将“ http-concat”目录及其内容复制到WordPress插件目录。 通过将以下内容添加到您的WordPress安装NGINX配置中,配置...
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装