项目移植或者转换经验交流

kuwoyinlehe 2012-08-20

最近公司在做一个项目的数据库迁移(SqlServer2008->MySql5.5)

考虑一:

1.对人员的影响(包括DBA及相应IT人员),在技能培训和操作习惯上需要多久才能适应,是否需要增加新的DBA;

2.数据库系统迁移所要耗费的时间以及对业务系统正常运行的影响程度有多大;

3.包括在前后期准备和迁移期间,都希望能够多大减少对业务系统的影响;

由于个人主要处理项目应用程序部分,因此从这方面出发:

1.调研分如下步骤:

1.收集资料,了解MySql版本历史

2.下载安装配置MYSql

3.通过项目Sql代码分析相应语法之间的差异,数据类型,函数

总结:

1、在SQLServer中,如果表名以数字开头,在SQL语句中我们需要在用“[”和“]”将表名括起来,例如:select*from[account_info]。但在MySQL中,它是不需要任何处理的,如:select*fromaccount_info,相反,这么做了反而会出错。

2、在SQLServer中常用的SelectTopn在MySQL中是不支持的,取而代之的是Limitn1,n2,但Limit在语法和功能上是与Top有很大不同的:首先,limitn1,n2必须放在整个SQL语句的最后,其次,Limitn1,n2取的不仅仅是前多少条,它可以取得记录集中的任意一个区段,从n1(包括n1)开始,到n2(不包括n2)结束。如果我们要取前10条记录,在SQLServer中应该这么写:selecttop10*from[account_info],而在MySQL中我们应该这么写:select*fromaccount_infolimit0,10。

3、在多表联合查找时,我们经常要给表一个别名,如:selecta.*,b.uidfromaccounta,dealerdwherea.uid=d.uid。这是在SQLServer中的写法,如果在MySQL中,我就应该这么写:selecta.*,b.uidfromaccount_infoasa,dealerasdwherea.uid=d.uid。

4、在MySQL中Groupby与Orderby不能同时使用。

5.收集的mysql与mssql的区别:

1)SQLServer和MySql语法和关键字的区别

——用于SQLServer到MySql的转换

(1)mysql的ifnull()函数对应sql的isnull()函数;

(2)mysql的存储过程中变量的定义去掉@;

(3)mysql的每句结束要用";

(4)SQLServer存储过程的AS在MySql中需要用begin.....end替换

(5)字符串连接用concat()函数;

如SQLServer:Temp=’select*from’+’tablename’+…+…

MySql:Temp=concat(’select*from’,’tablecname’,…,…)

(6)mysql的uuid()对应sql的GUID();

(7)MySql的out对应SQLServer的output,且mysql的out要放在变量的前面,SQLServer的output放在变量后面

MySqlout,in,inout的区别——

MySQL存储过程“in”参数:跟C语言的函数参数的值传递类似,MySQL存储过程内部可能会修改此参数,但对in类型参数的修改,对调用者(caller)来说是不可见的(notvisible)。

MySQL存储过程“out”参数:从存储过程内部传值给调用者。在存储过程内部,该参数初始值为null,无论调用者是否给存储过程参数设置值。

MySQL存储过程inout参数跟out类似,都可以从存储过程内部传值给调用者。不同的是:调用者还可以通过inout参数传递值给存储过程。

(8)MySQL的if语句为

if(条件)then

endif;

或者

If(条件)then

Else

Endif

或者

If(条件)then

Elseif(注意不能写成Elseif)

Elseif

Endif

(9)Mysql的Execute对应SqlServer的exec;

(注意:必须像下面这样调用)

Set@cnt=’select*from表名’;

Preparestrfrom@cnt;

Executestr;

(10)MySql存储过程调用其他存储过程用call

Call函数名(即SQLServer的存储过程名)(’参数1’,’参数2’,……)

(11)mysql的日期

○1获得当前日期函数:curdate(),current_date()

○2获得当前时间函数:curtime();

○3获得当前日期+时间:now();

○4MySQLdayof...函数:dayofweek(),dayofmonth(),dayofyear()分别返回日期参数,在一周、一月、一年中的位置。

(注:周日=1,周一=2,周二=3,……)

○5返回本月的天数:selectday(last_day(now()));

○6MySQL为日期增加一个时间间隔:date_add()

selectdate_add(CURRENT_DATE(),interval‘要增加的天数’day)asFdate

○7MySQL为日期减去一个时间间隔:date_sub()

selectdate_sub('1998-01-0100:00:00',interval'11:1:1'day_second);

○8MySQL日期、时间相减函数:datediff(date1,date2),timediff(time1,time2)

○9MySQL拼凑日期、时间函数:makdedate(year,dayofyear),maketime(hour,minute,second)

例:selectmakedate(2001,31);--'2001-01-31'

selectmakedate(2001,32);--'2001-02-01'

○10本周时间(起始)

selectdate_sub(CURRENT_DATE(),intervaldayofweek(curdate())-2day)asFdate

○11本周时间(结束)

selectdate_add(CURRENT_DATE(),intervaldayofweek(curdate())+3day)asFdate

○12上周时间(起始)

selectdate_sub(CURRENT_DATE(),intervaldayofweek(curdate())+5day)asFdate

○13上周时间(结束)

selectdate_sub(CURRENT_DATE(),intervaldayofweek(curdate())-1day)asFdate

○14本月时间(起始)

selectDATE_SUB(CURDATE(),INTERVALDAY(CURDATE())-1DAY)asFdate

○15本月时间(结束)

Selectdate_add(current_date(),intervalday(last_day(CURDATE()))-day(CURDATE())day)asFdate

○16上月时间(起始)

selectDATE_SUB(DATE_SUB(CURDATE(),INTERVALDAY(CURDATE())DAY),intervalday(last_day(DATE_SUB(CURDATE(),INTERVALDAY(CURDATE())DAY)))-1day)asFdate

○17上月时间(结束)

selectDATE_SUB(CURDATE(),INTERVALDAY(CURDATE())DAY)asFdate

○18今年时间(起始)

selectmakedate(year(curdate()),1)asFDate

○19今年时间(结束)

selectDATE_SUB(makedate(year(curdate())+1,1),INTERVAL1day)asFdate

○20去年时间(起始)

selectmakedate(year(curdate())-1,1)asFdate

○21去年时间(结束)

selectDATE_SUB(makedate(year(curdate()),1),INTERVAL1day)asFDate

○22DATE_FORMAT(date,format):根据format字符串格式化date值。下列修饰符可以被用在format字符串中

%M月名字(January……December)

%W星期名字(Sunday……Saturday)

%D有英语前缀的月份的日期(1st,2nd,3rd,等等。)

%Y年,数字,4位

%y年,数字,2位

%a缩写的星期名字(Sun……Sat)

%d月份中的天数,数字(00……31)

%e月份中的天数,数字(0……31)

%m月,数字(01……12)

%c月,数字(1……12)

%b缩写的月份名字(Jan……Dec)

%j一年中的天数(001……366)

%H小时(00……23)

%k小时(0……23)

%h小时(01……12)

%I小时(01……12)

%l小时(1……12)

%i分钟,数字(00……59)

%r时间,12小时(hh:mm:ss[AP]M)

%T时间,24小时(hh:mm:ss)

%S秒(00……59)

%s秒(00……59)

%pAM或PM

%w一个星期中的天数(0=Sunday……6=Saturday)

%U星期(0……52),这里星期天是星期的第一天

%u星期(0……52),这里星期一是星期的第一天

%%一个文字“%”。

例:所有的其他字符不做解释被复制到结果中。

mysql>selectDATE_FORMAT('1997-10-0422:23:00','%W%M%Y');

->'SaturdayOctober1997'

mysql>selectDATE_FORMAT('1997-10-0422:23:00','%H:%i:%s');

->'22:23:00'

mysql>selectDATE_FORMAT('1997-10-0422:23:00','%D%y%a%d%m%b%j');

->'4th97Sat0410Oct277'

mysql>selectDATE_FORMAT('1997-10-0422:23:00','%H%k%I%r%T%S%w');

->'22221010:23:00PM22:23:00006'

(12)MySql存储过程中没有return函数,在MySql中可以用循环和out参数代替

IfEXISTS(SELECT*FROMT_ChanceWHEREFCustID=CostomerID)return0

改写为:

(在参数中定义一个out变量:outtempvarchar(100);)

BEGIN

Loop1:loop

SELECTcount(*)FROMT_ChanceWHEREFCustID=CostomerIDint@cnt

If@cnt>0then

begin

settemp=0;

leaveloop1;

end;

endif

endlooploop1;

(13)select@a=count(*)fromVW_Action在mySql中修改为:selectcount(*)fromVW_Actioninto@a;

(14)MySQL中没有top关键字,需要用limit代替且放在后面

注意,在MySQL中的limit不能放在子查询内,limit不同与SQLServer,它可以规定范围limita,b——范围a-b

SQLSERVER:selecttop8*fromtable1

MYSQL:select*fromtable1limit5;

(15)即使存储过程没有参数也要写括号“()”

(16)当一个存储过程中有创建临时表时

createprocedureup_test

()

begin

droptableifexiststb1;

createTEMPORARYtabletb1//注意添加TEMPORARYtable

(

idint,

namevarchar(20)

);//注意最后加分号

inserttb1values('1','jim');

select*fromtb1;

end

(17)建表中自增长问题:

createtableuser

(

Idvarchar(10)primarykeyauto_incrementnotnull,

Namevarchar(20)notnull,

Passwordvarchar(20),

create_datedatetime

);

auto_increment自增长

(18)"UnabletoconvertMySQLdate/timevaluetoSystem.DateTime"这是因为在日期列中有"0000-00-00"数据值,要修正这个问题,你可以把这些数据设为null,或者在连接字符串中设置"AllowZeroDatetime=True"。

(19)MySQL视图的FROM子句不允许存在子查询,因此对于SQLServer中FROM子句带有子查询的视图,需要手工进行迁移。可通过消除FROM子句中的子查询,或将FROM子句中的子查询重构为一个新的视图来进行迁移。

(20)类型转换:

text----longtext

float----double

tinyint---bit

int---int

image--longblob

今天暂且做第一点,稍后继续更新,希望大侠能够给些建议

4.把数据库从SQLServer迁移到MySQL,可以在MySQL中重新构建一个一模一样的空数据库,然后用程序代码把数据从SQLServer中读出再写入MySQL中。这种方法当然不会有错,然而有更方便的方法:SQLServer有导入导出功能,我们可以使用它的导出功能,将SQLServer中的数据完整的导出到MySQL中。

5.初步尝试一个简单的设置,进行Web项目的移植,最先需要确认其对数据库访问的正确性。因此需要在安装的Jboss5.1先设置一个数据库连接池,以保证Web应用程序对数据库访问的可行性。需要注意的是需要在数据源中为该数据源设置一个J2EE连接器体系结构(J2C)认证。在设置了连接数据源的用户名和密码以后,在数据源的组件管理的认证别名中选择刚才设置的认证。在以上配置工作完成以后就可以对该数据连接池进行连接测试了。

在数据连接池测试成功以后,就需要考虑在Web应用程序如何取调用该数据连接池进行数据库连接了。访问应用服务器的数据连接池肯定是通过JNDI进行访问。[/size][/size][/size]

相关推荐