目录
由于近期一部分项目的测试环境需要从oracle迁移至mysql,所以做了一下数据库表的迁移,其中也遇到了一些问题,因此记录一下
一、利用Navicat将oracle迁移至mysql数据库
1、建立数据传输
2、选择需要迁移的数据库跟目标库
3、数据传输选项
4、选择需要迁移表信息
选好需要同步的表之后点击开始即可
二、迁移之后遇到的一些问题
1、大小写问题
由于oracle不区分大小写,所以同步过来的表及字段我默认为全部大写,但是在系统中表名并不是全部大写,比如一个mysqlTest表,数据库中是MYSQLTEST,但是程序中的sql是 SELECT * FROM mysqlTest,那就会报错mysqlTest表不存在,因此需要设置mysql不区分大小写。
进入mysql的my.cnf目录下,比如/etc/my.cnf,然后在后边加上 lower_case_table_names=1
lower_case_table_names=1
然后重启mysql即可。
2、数据库函数问题
比如一些 Unknown column 'sysdate' in 'where clause' ,oracle使用sysdate来取当前时间,mysql则需要加括号sysdate(),或者使用 CURRENT_TIMESTAMP(),包括其他截取,分页(limit跟rownum)等就不赘述
3、sql语句是否使用空格隔开问题
oracle中使用以下语句 ,可以正常查询,但是在mysql中则会报错
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a.age<21' at line 1
sql
SELECT * from test a WHERE a.id>10and a.age<21 ;
在10和and之间加一个空格即可解决
sql
SELECT * from test a WHERE a.id>10 and a.age<21 ;
4、关于子查询别命名问题
比如分页的时候可以这样查询总数,oracle可以正常返回,mysql则会报错
> 1248 - Every derived table must have its own alias
sql
SELECT count(*) FROM(SELECT * from test );
需要给子查询加一个别命名
sql
SELECT count(*) FROM(SELECT * from test ) a;
5、数据库自增问题
oracle中可以使用序列号自增,select SEQ_TESTNO.nextVal from dual ;在使用的时候可以直接获取到序列号的值,但是mysql中则不能直接使用,会报错 Unknown table 'SEQ_TESTNO' in field list,为了减小改动量就建一个表用来保存序列号,然后写一个获取下一个序列号的函数,用来获取。
建表
sql
CREATE TABLE `sequence` (
`name` varchar(255) COLLATE utf8_bin NOT NULL COMMENT '序列号名称',
`current_value` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '当前值',
`increment` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '增长量',
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
获取当前值
sql
DROP FUNCTION IF EXISTS currval;
DELIMITER $
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM sequence
WHERE name = seq_name;
RETURN value;
END
$
DELIMITER ;
获取下一个值
sql
DROP FUNCTION IF EXISTS nextval;
DELIMITER $
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = current_value + increment
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
插入序列号名称
查询的时候只需要
SELECT NEXTVAL('SEQ_TESTNO') from dual; 即可