虾米窝窝 -- » 笔记:MySQL迁移到MSSQL
Subscribe RSS
笔记:MySQL迁移到MSSQL 02月 25

     最近一个项目是基于discuz的东西做二次开发,总所周知,Discuz的东西是那个猛啊,完全是面向过程的写法,不过效率超级高,完全是PHP+MySQL的经典之作,但是……这个客户以前的系统用的是MSSQL,他要我们把Discuz从MySQL迁移到MSSQL,那个囧啊。
     要知道俺已经不用MSSQL很多年了,印象中还停留在SQL Server2000上,现在是要重新学一下2005了。
     鉴于这个迁移很有挑战性,我觉得很有必要把途中遇到的东西记录下来,并不断更新,方便自己和需要的同学用。
    下面开始了:

一、数据库迁移规则
1. SQL Server不支持UTF-8,多国语言字段请使用unicode的nchar, nvarchar类型。
2. MySQL中的smallint值范围是0~65535,SQL Server中换用int值范围(-2,147,483,648)到(2,147,483,647)
3. MySQL中的mediumint值范围是0~16777215,SQL Server中换用int值范围(-2,147,483,648)到(2,147,483,647)
4. MySQL中的int值范围是0~4,294,967,295,SQL Server中换用numeric(10,0)
5. MySQL中的tinyint值范围是0~255,SQL Server中使用tinyint值范围是0~255
6. MySQL中的char类型,在SQL Server中,如果字符串长度相差不大,使用char和nchar类型查询效率较高,如果是长度相差较大,使用varchar和nvarchar。
7. MySQL中的varchar类型,如果可能有非英文字符,SQL Server中使用nvarchar类型(最大4000)。
8. MySQL中的text类型,如果可能有非英文字符,SQL Server中使用nvarchar(max)类型。注意,text类型将在未来版本删除。
9. SQL Server中,char和varchar字符串长度小于8000,nchar和nvarchar长度小于4000。
10. MySQL中的char类型也是要在末尾补空格的,但是查询时候trim掉了,在SQL Server中不trim。
11. MySQL中的key,在SQL Server中使用index。

二、SET IDENTITY_INSERT tablename ON
1.每一次连接会话中的任一时刻,只能对一个表设置IDENTITY_INSERT ON,且设置只对当前会话有效;
2.在对标识列执行插入操作进,一定要列出此标识列(当然,同时也就需要列出相关的其他列了)。

三、关于ntwdblib.dll
是SQL SERVER客户端连接库,在版本不对的情况下可能会导致PHP无法连接到SQL Server,建议下载最新版本的ntwdblib.dll来使用。另外在某些情况下ntwdblib.dll也会存在于Apache目录下,所以在覆盖ntwdblib.dll的时候要同事覆盖PHP目录和Apache目录。

四、关于编码问题
本身不支持UTF-8,多语言保存数据需要用ntext和nvarchar字段(unicode),因此php通过mssql扩展读取带ntext和nvarchar类型字段的时候会报错:Warning: mssql_query() [function.mssql-query]: message: 不能用 DB-Library (如 ISQL)或 ODBC 3.7 或更早版本将 ntext 数据或仅使用 Unicode 排序规则的 Unicode 数据发送到客户端。 (severity 16)。
如果username字段类型为 nvarchar,description字段类型为 nchar(MAX) ,那么下面的sql语句会报错:
select username,description from user
正确的写法是:
select convert(varchar(255),username) as username, convert(description,char(MAX)) as description from user

五、mssql_result问题
uchome中一般把string mysql_result ( resource result, int row, mixed field )中最后一个, mixed field去掉了,迁移到mssql后会出现问题,解决办法是加上需要的字段名,类似"SELECT COUNT(*) FROM tablename"中字段名应该写成computed.

六、replace into问题
在SQL Server中没有replace into 语法,需要用:
IF EXISTS (SELECT * FROM [Table] WHERE Id = X)   UPDATE [Table] SET…ELSE   INSERT INTO [Table]

七、编码
不知道为什么SQL Server为什么就不支持一下utf8呢?又或者是不搞一个好一点的PHP连接对象?看到手册上写的text字段不久以后就会被抛弃了,所以不推荐使用,我们还傻乎乎的照着做了,都是想的要考虑久远一点嘛。所以我们在有大量text的地方都用的nvarchar(MAX),但是问题出来了,php在读取数据的时候不能把字符全部读出来:比如我文章主体有500个字,从数据库客户端看到是好好的,但是php就是只能读出几个字!晕了,攻克这个难关的同学搞了好久也搞不定,最后没有办法,用GBK字符集,一下就好了。囧啊…

———————–占位符——————-
此文会不断更新,直到此项目结束……………..

Category: PHP&MySQL  | 标签: , , , ,  | 799次阅读
你可以通过RSS 2.0来关注此文章的评论. 也可以留言或者从你的主页trackback.
留言

XHTML: 你可以使用以下的标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>