作者介紹
農(nóng)行研發(fā)中心“數(shù)風(fēng)云”團(tuán)隊,一支朝氣蓬勃、快速成長的技術(shù)團(tuán)隊,始終致力于農(nóng)行大數(shù)據(jù)、數(shù)據(jù)庫和云計算等領(lǐng)域的應(yīng)用實踐與技術(shù)創(chuàng)新,探索數(shù)據(jù)賦能,勇攀數(shù)據(jù)云巔,為企業(yè)數(shù)字化轉(zhuǎn)型和金融科技發(fā)展不斷貢獻(xiàn)力量。
背景介紹
筆者在工作中曾遇到SyBase數(shù)據(jù)庫遷移至MySQL時的一個問題:使用bcp將SyBase中的數(shù)據(jù)導(dǎo)出為csv文件時,datetime數(shù)據(jù)類型默認(rèn)導(dǎo)出格式與MySQL不兼容。Sybase默認(rèn)的datetime類型格式為Mmm dd yyyy hh:nn:ss:sssAA,示例如下:
Dec 24 2017 12:00:00:000PM
而MySQL中datetime類型格式為yyyy-mm-dd hh:nn:ss,示例如下:
2017-12-24 12:00:00
因此直接將csv文件導(dǎo)入MySQL會由于不兼容導(dǎo)致報錯。
解決方式
解決此問題的方式不外乎兩種:一是修改導(dǎo)出后的csv文件,令其時間字段的數(shù)據(jù)格式兼容MySQL;二是修改SyBase數(shù)據(jù)庫中時間字段的數(shù)據(jù)格式,使其直接能通過bcp導(dǎo)出兼容MySQL的csv文件。鑒于第一種方法較為復(fù)雜,本文筆者采用第二種方法解決該問題。
1、convert()函數(shù)介紹
convert()函數(shù)是SyBase數(shù)據(jù)庫中用于數(shù)據(jù)類型轉(zhuǎn)換的函數(shù),其使用方式如下:
convert(datatype,expression,[format-style])
- datatype:必選參數(shù),將要轉(zhuǎn)換成的數(shù)據(jù)類型;
- expression:必選參數(shù),待轉(zhuǎn)換的字段;
- format-style:可選參數(shù),轉(zhuǎn)換時間類型時,決定輸出格式的參數(shù),對應(yīng)關(guān)系見下表:
format-style的值 |
輸出格式 |
輸出示例 |
100 |
Mmm dd yyyy hh:nnAA |
Dec 24 2017 12:00PM |
101 |
mm/dd/yyyy |
12/24/2017 |
102 |
yyyy.mm.dd |
2017.12.24 |
103 |
dd/mm/yyyy |
24/12/2017 |
104 |
dd.mm.yyyy |
24.12.2017 |
105 |
dd-mm-yyyy |
24-12-2017 |
106 |
dd Mmm yyyy |
24 Dec 2017 |
107 |
Mmm dd,yyyy |
Dec 24,2017 |
108 |
hh:nn:ss |
12:00:00 |
109 |
Mmm dd yyyy hh:nn:ss:sssAA |
Dec 24 2017 12:00:00:000PM |
110 |
mm-dd-yyyy |
12-24-2017 |
111 |
yyyy/mm/dd |
2017/12/24 |
112 |
yyyymmdd |
20171224 |
例如有一個名為test的表,將該表中一個名為changetime,類型為datetime的字段轉(zhuǎn)換為varchar類型,可以使用如下SQL語句:
select convert(varchar(100),changetime,111) as dates from test;
若該字段僅有一行數(shù)據(jù),其值為Dec 24 2017 12:00:00:000PM,那么以上SQL輸出的結(jié)果為2017/12/24.
2、str_replace()函數(shù)介紹
str_replace()參數(shù)用于替換字符串中的部分字符,其使用方式如下:
str_replace(‘string1’,’string2’,’string3’)
參數(shù)含義:
- string1:必選參數(shù),原始字符串;
- string2:必選參數(shù),待轉(zhuǎn)換的字符;
- string3:必選參數(shù),需要轉(zhuǎn)換成的字符;
例如以下SQL:
select str_replace(‘2017/12/24’,’/’,’-’);
其輸出結(jié)果為2017-12-24.
3、具體方案實施
由以上示例可見,若將SyBase中datetime類型字段使用convert()函數(shù)轉(zhuǎn)換為varchar類型,format-style的值指定為111,再使用str_replace()函數(shù),將convert()轉(zhuǎn)換來的字符串中的’/’轉(zhuǎn)換為’-’,即可滿足MySQL中對datetime類型的格式要求(yyyy-mm-dd);同理,format-style的值指定為108,即可滿足hh:nn:ss的格式要求。具體的實施方案舉例說明如下:
1)在SyBase數(shù)據(jù)庫建立一張臨時表tmp,表結(jié)構(gòu)與待導(dǎo)出數(shù)據(jù)的表test一致,僅datetime類型字段改為varchar類型;表結(jié)構(gòu)見以下SQL語句:
create table test(id int,time datetime);
create table tmp(id int,time varchar(100));
2)采用如下SQL語句將原始表的數(shù)據(jù)存入臨時表中:
insert into tmp select id,str_replace(convert(varchar(100),time,111),'/','-')
+' '+convert(varchar(100),time,108) from test;
3)將臨時表tmp中的數(shù)據(jù)使用bcp命令導(dǎo)出為csv文件;
4)將csv文件中的數(shù)據(jù)導(dǎo)入MySQL數(shù)據(jù)庫對應(yīng)表中。
至此,解決了SyBase中datetime類型字段默認(rèn)導(dǎo)出格式與MySQL不兼容的問題。
關(guān)注公眾號【dbaplus社群】,獲取更多原創(chuàng)技術(shù)文章和精選工具下載