Mysql迁移到Oracle简单记录

因业务的扩展和客户的要求,公司需要将原运行于Mysql上的数据迁移至Oracle。

参加工作的最初几年短暂接触过Mysql,但不经常使用,最初的印象已经所剩无几了。

本文主要记录在数据库迁移过程中,遇到相关问题的解决办法。主要集中于数据类型的选择、部分函数的替代以及其他数据库之间差异的问题。

对于存在相同需求的同学,能够有一点点帮助,我会感到很欣慰 : )

1.数据类型的选择。

数值类型:

Mysql有两种类型的数字:整数(whole number)和实数(real number).

存储整数可以选择:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT  ,分别对应8,16,24,32,64位存储空间。他们可存储的范围从-2的N-1次方到2的N-1次方-1,其中N是存储空间的位数。

整数类型有可选的UNSIGNED属性,表示不允许负值,这大致可以使正数的上限提高一倍。例如TINYINT  UNSIGNED可以存储的范围是0~255,而TINYINT的存储范围是-128-127.

实数是带有小数部分的数字。DECIMAL类型用于存储精确的小数。因为额外的计算和开销,应该尽量只是在对小数进行精确计算时才使用。在数据量比较大时,可以考虑用bigint代替DECIMAL。

相比较而言,Oracle有number,int,float,binary_float,binary_double,numeric类型

number类型在oracle中会占用0~22个字节的存储空间,是一种变长数据类型,采用oracle内部算法,是一种软数据类型,因此具有较好的数据精确度,通用性和可移植性较强

其中如下的这些类型都是从number类型映射而来。

NUMERIC(p,s):完全映射至NUMBER(p,s)。如果p未指定,则默认为38.

DECIMAL(p,s)或DEC(p,s):完全映射至NUMBER(p,s)。如果p为指定,则默认为38

INTEGER或INT:完全映射至NUMBER(38)类型。

SMALLINT:完全映射至NUMBER(38)类型

由于存储结构上的不同,BINARY_FLOAT和BINARY_DOUBLE较number,可以存储更大范围的数据,但是其精度并不如number。如果存储金融数据,建议使用number。

而如果进行科学运算,建议使用BINARY_FLOAT和BINARY_DOUBLE,因为浮点型数据使用的是硬件计算,其计算效率是非常高的。

对于Mysql中的各种int类型,建议统一都对应到Oracle的number类型。(number(p,s)也是完全映射到number类型的,所以无需设置精度)

字符类型:

Mysql使用VARCHAR和CHAR两种类型。

VARCHAR是变长类型

CHAR是定长类型

CHAR这类定长类型,会删除所有末尾的空格,在数据存储和比较的时候,某些行为就难以理解。所以正常选择VARCHAR为好。

Oracle中char属于定长类型会使用空格进行填充。

而varchar2采用变长的方式存储数据,相对会节省空间。在存储效率上,与char不相上下。

另外char类型同样存在末尾空格的问题。

对于Oracle类型,由于工作习惯以及存储的要求来考虑,应该尽可能的选择varchar2。

2.Mysql中delimiter的作用

该关键字是告诉解释器,该段命令是否已经结束,mysql是否可以执行后续脚本。

DELIMITER ;
DROP PROCEDURE IF EXISTS p_contract;  --该语句可以立即执行
DELIMITER $$    -- 并没有以分号结束,后续语句等待遇到$$时执行。
CREATE PROCEDURE p_contract()
    BEGIN
。。。。。。
。。。。。
    END $$  -- 执行中间的语句。
DELIMITER ;

3.DECLARE CONTINUE HANDLER FOR NOT FOUND

若没有数据返回,程序继续,并将变量IS_FOUND设为0 ,这种情况是出现在select XX into XXX from  tablename的时候发生的。

4.UNIX时间戳与日期的相互转换

Mysql中日期以及时间函数,推荐你可以看一下这篇文章:http://www.cnblogs.com/redfox241/archive/2009/07/23/1529092.html

Oracle获取UTC时间:

select to_char(sys_extract_utc(systimestamp),‘yyyy-mm-dd hh24:mi:ss‘) from  dual;     --UTC时间

mysql中UNIX时间戳与日期的相互转换

UNIX时间戳转换为日期用函数:FROM_UNIXTIME()

select FROM_UNIXTIME(1410318106);

日期转换为UNIX时间戳用函数:UNIX_TIMESTAMP()

select UNIX_TIMESTAMP(‘2014-09-10 11:01:46‘);

where DATE_FORMAT(FROM_UNIXTIME(‘1410318106‘,‘%Y-%m-%d %h:%m:%s‘),‘%Y-%m-%d  %h:%m:%s‘)

Oracle并没有这类的转换函数,需要自己写(如下的写法也来自网络)

--Oracle时间Date型转换为Unix时间戳
create or replace function bill_query.oracle_to_unix(in_date DATE) return number is
BEGIN
   
   return( (in_date -TO_DATE(‘19700101‘,‘yyyymmdd‘))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600);
END oracle_to_unix;
/
--Unix时间戳转换为Oracle时间
create or replace function bill_query.unix_to_oracle(in_number NUMBER) return date is
BEGIN
    
    return(TO_DATE(‘19700101‘,‘yyyymmdd‘) + in_number/86400 +TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))/24);
END unix_to_oracle;

/

5.Mysql中的索引和约束与Oracle的对应


primary key  ---> primary key

index ---> index

unique key –> unique index

key --->  index

7.AUTO_INCREMENT属性

Mysql 中字段存在AUTO_INCREMENT属性,Oracle中需要使用序列代替。

在用到该字段时,需要显式的调用,插入sequence_name.nextval

8.Mysql创建表时可以通过语句查询表是否存在并删除(drop database if  exists  table_name)

Oracle中可以通过自定义函数来实现。(函数中存在DDL语句时,不能通过select的方式调用,只能通过赋值的方式。这里可以考虑在存储过程中实现并调用会更方便一点。)

create or replace function hytpdtnmdb.fun_obj_ifexists(v_obj_name in  varchar2) return number  is
    num_tab   number;
    num_seq    number;
begin
      select count(1) into num_tab from all_objects where  OWNER||‘.‘||OBJECT_NAME = upper(v_obj_name) and OBJECT_TYPE=‘TABLE‘;
      if  num_tab = 1 then
         execute immediate ‘drop table  ‘||v_obj_name;
         return(num_tab);
      end if;
      select count(1) into num_seq from all_objects where  OWNER||‘.‘||OBJECT_NAME = upper(v_obj_name) and OBJECT_TYPE=‘SEQUENCE‘;
       IF num_seq = 1 THEN
         EXECUTE IMMEDIATE ‘drop SEQUENCE  ‘||v_obj_name;
         RETURN num_seq;
      END IF;
      return  -1;
end fun_obj_ifexists;

9.关于Oracle存储过程执行权限问题

在A用户,需要更新、删除、drop table 或 create table  B用户对象的情况。
即便给用户赋予DBA权限,在匿名存储过程或在command窗口,可以正常执行,在存储过程中会存在权限不足的情况。

通过网上查阅资料,通过添加AUTHID  CURRENT_USER。 以CREATE OR REPLACE procedure DEMO(ID in NUMBER) AUTHID  CURRENT_USER as的方式创建存储过程可以解决。
文章链接:http://blog.csdn.net/gavinloo/article/details/6869234

但偶尔仍然存在权限不足的问题,可以通过grant显式授权的方式解决。

10.部分函数的差别

  • Mysql中concat可以连接多个字符串。Oracle中只能连接两个字符。如果需要多个字符串的连接,仍然要使用‘||‘
  • NUMTOYMINTERVAL ( n , ‘char_expr‘ )
      char_expr:日期描述,可以是YEAR和MONTH;
  • NUMTODSINTERVAL( n , ‘char_expr‘ )

    char_expr:时间描述,可以是day、hour、minute、second;
     
      interval后面只能用数字

  • 正常情况下都可以使用 interval,但是当需要增加或减少的数值为变量时,只能用

numtodsinterval 和 NUMTOYMINTERVAL  替代。

时间: 2024-10-28 21:00:47

Mysql迁移到Oracle简单记录的相关文章

将数据从MySQL迁移到Oracle的注意事项

1.自动增长的数据类型处理MYSQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值.ORACLE没有自动增长的数据类型,需要建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段.CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记)INCREMENT BY 1 START WITH 1 MAXVALUE 99999 CYCLE NOCACHE;INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL 2. 单引号的处理MYSQL里可以用

迁移mysql数据到oracle上

转自:http://www.cnblogs.com/Warmsunshine/p/4651283.html 我是生成的文件里面的master.sql里面的sql,一个一个拷出来的. 迁移mysql数据到oracle上 一.   服务器本地安装Oracle11G或10G 二.   在运行中输入sqlplus /nolog,oracle中创建表空间. 三.   安装完成后在运行中输入 sql developer打开sql developer (就是本机自带的) 四.   选择jdk版路径(jdk版本

Linux 上从 MySQL 迁移到 MariaDB 的简单步骤

大家好!这是一篇介绍如何在服务器或个人电脑上从MySQL迁移到MariaDB的教程.也许你会问为什么我们要将数据库管理从MySQL迁移到MariaDB.往下看我们告诉你为什么这样做.为什么要用MariaDB来代替MySQLMariaDB是MySQL社区开发的分支,也是一个增强型的替代品.它由MySQL前开发者们带头组织的基金会开发,使用起来和MySQL完全一样.自从Oracle买下了MySQL,它就不再自由开源了,但是MariaDB仍然自由开源.一些如谷歌.维基.LinkedIn.Mozilla

MySQL 迁移 Oracle 工具SQL Developer

业务需求,需要将MySQL数据库内容迁移至Oracle数据库中,数据量在300g左右,为了方便,通过Oracle自己的工具SQLDeveloper迁移,步骤如下: 下载mysql-connector-java-5.1.24驱动,存放在C:\sqldeveloper\jlib目录下 配置mysql-connector第三方驱动 链接MySQL及Oracle数据库 创建MySQL移植资料库 创建ORACLE migration user create user migrater identified

mysql 迁移数据库到 oracle (sql注意问题)

http://ykdn2010.iteye.com/blog/1511349 一. 项目已用到 oracle 函数的转换 1.  Oracle 中的 TO_DATE (),TO_CHAR () 示例: select * from admadjustmoney t where t.sendtime> to_date(?,'yyyy-mm-dd      hh24:mi:ss') and t.sendtime< to_date(?,'yyyy-mm-dd hh24:mi:ss') 转换后: SEL

核心业务系统数据库平台迁移: Oracle -&gt; MySQL

为了对核心技术拥有更多的自主控制能力,为了解决数据库的线性扩展问题,为了尽量减少对商业软件的依赖,为了摆脱对高端硬件的依赖,为了… 基于以上多种原因,2年前,我们计划将公司某核心应用平台进行大手术:数据库平台从软件到硬件全部重构.当然,这其中应用架构的改造也不可避免的进行了大换血. 这个项目无论是从技术角度还是是业务角度来说,都对我们有着非常大的价值,也必定会带来非常深远的影响.项目历时2年多,分4个阶段才完成: 应用接口统一 这一阶段主要是为了后面真正迁移的时候做准备工作,将该核心应用系统的所

数据库迁移之-Oracle 与MySQL互相转换

理论上来说, MySQL 已经被Oracle 收购, 这两者之间的Migrate 应该比较容易, 但实际的迁移还是有一些问题, 以下就说一说一些实现的方式和问题. 方式一:手动方式导入导出 手动的方式导入, 就是操作步骤会比较繁琐一些. 对Table 的结构和数据: 1. 使用 SQL Developer 把 oracle 的 table 的schema 和 Data(.sql 和 .xls) 导出 2. 使用 MySQL 的 WorkBench 创建 Table 和导入数据. 这里语法上会稍微

数据库 SQL Server 到 MySQL 迁移方法总结

最近接手一起老项目数据库 SQL Server 到 MySQL 的迁移.因此迁移前进行了一些调查和总结.下面是一些 SQL Server 到 MySQL 的迁移方法. 1. 使用 SQLyog 迁移 具体方法可以参加:http://www.cnblogs.com/gaizai/p/3237907.html 优点:该迁移方法很简单,灵活,迁移时,可以进行字段的修改,比如在sql server中原来是datetime,然后迁移到mysql时你可以配置成timestamp: 成功率很高: 缺点:迁移很

Mysql调试存储过程最简单的方法

以前同事告诉我用临时表插入变量数据来查看,但是这种方法过于麻烦,而且Mysql没有比较好的调试存储过程的工具.今天google了下发现可以用select + 变量名的方法来调试...真是让我汗颜啊. 具体方法: 在你的存储过程中加入如下语句: SELECT 变量1,变量2; 然后用mysql自带的cmd程序进入mysql> 下. call 你的存储过程名(输入参数1,@输出参数);(注:这里帮助下新同学,如果你的存储过程有输出变量,那么在这里只需要加 @ 然后跟任意变量名即可); 即可发现你的变