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')
转换后:
SELECT *
FROM `ADMADJUSTMONEY` t
WHERE t.SENDTIME > STR_TO_DATE(sysdate(), '%Y-%m-%d %h:%i:%s') AND
t.SENDTIME < STR_TO_DATE(sysdate(), '%Y-%m-%d %h:%i:%s') 注意表名字段名的大小写 MYSQL 大小写敏感 sql 统一大写 hql 统一小写
2. Oracle 中的 nvl ()
示例 : select distinct a.id,a.parentId,a.description,a.name,a.status, NVL(ur.roleid,'')AS roleid from admrole a left join admuserrole ur on (a.id = ur.roleid and ur.userid = ? and ur.status = 1) where a.status = ?
转换后:
select distinct a.id,a.parentId,a.description,a.name,a.status, IFNULL(ur.roleid,'') AS roleid from admrole a left join admuserrole ur on (a.id = ur.roleid and ur.userid = ? and ur.status = 1) where a.status = ?
3. Oracle 中的 decode ()
示例:
SELECT DECODE(MAX(PIECECODE), NULL, 0, MAX(PIECECODE)) AS PIECECODE FROM PUBPAGEPIECE WHERE 1=1
转换后:
SELECT if(MAX(PIECECODE) IS NULL, 0, MAX(PIECECODE)) AS PIECECODE FROM PUBPAGEPIECE WHERE 1=1
或者用 case when 的标准写法
SELECT
CASE
WHEN MAX(PIECECODE) IS NULL THEN 0
WHEN MAX(PIECECODE) IS NOT NULL THEN MAX(PIECECODE)
END AS PIECECODE
FROM PUBPAGEPIECE WHERE 1=1
4. Oracle 中的 substr ()
示例: WHERE t.aid = v.aid and t.province = v.province and t.city = v.city and t.wid = w.id AND w.startdate>=to_date( substr(?,1,10) ,'yyyy-MM-dd') and w.stopdate<=to_date( substr(?,1,10) ,'yyyy-MM-dd')
转换后:
WHERE t.aid = v.aid and t.province = v.province and t.city = v.city and t.wid = w.id AND w.startdate>= STR_TO_DATE ( substring (?,1,10) , '%Y-%m-%d' ) and w.stopdate<=STR_TO_DATE ( substring (?,1,10) , '%Y-%m-%d' )
5. Oracle 中的 trunc ()
示例:
from PUBCOINOPDETAIL where opervirtualCoin > 0 and status = 1 and operTime >= ADD_MONTHS(TRUNC(SYSDATE,'mm') ,-1) and operTime < TRUNC(SYSDATE,'mm') group by gene , geneType ,accountId
转换后:
from PUBCOINOPDETAIL where opervirtualCoin > 0 and status = 1 and operTime >=DATE_SUB(date_sub(CURDATE(),INTERVAL EXTRACT( day from CURDATE())-1 day),INTERVAL 1 MONTH) [ 上个月第一天 ] and operTime <DATE_SUB(date_sub(CURDATE(),INTERVAL EXTRACT(day from CURDATE())-1 day),INTERVAL 0 MONTH) [ 这个月第一天 ] group by gene , geneType ,accountId
6、Oracle 中的 wm_concat (),NVL()
0:dbms_lob.substr()sql上mysql clob 转String
o:dbms_lob.substr(wm_concat(NVL(count,0))) count
m:dbms_lob.substr(GROUP_CONCAT(IFNULL(count,0))) count,
7、oracle
o:is not null,is null
msql :is not null ,is null , XX!=' '
再次提醒 mysql 大小写的问题 sql 统一大写 hql 统一小写 避免不必要的 BUG 出现
二.网络资料附表:oracle 常用函数 与mysql 的对照表 s:mysql o :oracle
1. 绝对值
S:select abs(-1) value
O:select abs(-1) value from dual
2. 取整 ( 大 )
S:select ceiling(-1.001) value
O:select ceil(-1.001) value from dual
3. 取整(小)
S:select floor(-1.001) value
O:select floor(-1.001) value from dual
4. 取整(截取)
S:select cast(-1.002 as int) value
O:select trunc(-1.002) value from dual
5. 四舍五入
S:select round(1.23456,4) value 1.23460
O:select round(1.23456,4) value from dual 1.2346
6.e 为底的幂
S:select Exp(1) value 2.7182818284590451
O:select Exp(1) value from dual 2.71828182
7. 取 e 为底的对数
S:select log(2.7182818284590451) value 1
O:select ln(2.7182818284590451) value from dual; 1
8. 取 10 为底对数
S:select log10(10) value 1
O:select log(10,10) value from dual; 1
9. 取平方
S:select SQUARE(4) value 16
O:select power(4,2) value from dual 16
10. 取平方根
S:select SQRT(4) value 2
O:select SQRT(4) value from dual 2
11. 求任意数为底的幂
S:select power(3,4) value 81
O:select power(3,4) value from dual 81
12. 取随机数
S:select rand() value
O:select sys.dbms_random.value(0,1) value from dual;
13. 取符号
S:select sign(-8) value -1
O:select sign(-8) value from dual -1
14. 圆周率
S:SELECT PI() value 3.1415926535897931
O: 不知道
15.sin,cos,tan 参数都以弧度为单位
例如: select sin(PI()/2) value 得到 1 ( SQLServer )
16.Asin,Acos,Atan,Atan2 返回弧度
17. 弧度角度互换 (SQLServer , Oracle 不知道 )
DEGREES :弧度 - 〉角度
RADIANS :角度 - 〉弧度
数值间比较
18. 求集合最大值
S:select max(value) value from
(select 1 value
union
select -2 value
union
select 4 value
union
select 3 value)a
O:select greatest(1,-2,4,3) value from dual
19. 求集合最小值
S:select min(value) value from
(select 1 value
union
select -2 value
union
select 4 value
union
select 3 value)a
O:select least(1,-2,4,3) value from dual
20. 如何处理 null 值 (F2 中的 null 以 10 代替 )
S:select F1,IFNull(F2,10) value from Tbl
O:select F1,nvl(F2,10) value from Tbl
21. 求字符序号
S:select ascii('a') value
O:select ascii('a') value from dual
22. 从序号求字符
S:select char(97) value
O:select chr(97) value from dual
23. 连接
S:select '11'+'22'+'33' value
O:select CONCAT('11','22') 33 value from dual
23. 子串位置 -- 返回 3
S:select CHARINDEX('s','sdsq',2) value
O:select INSTR('sdsq','s',2) value from dual
23. 模糊子串的位置 -- 返回 2, 参数去掉中间 % 则返回 7
S:select patindex('%d%q%','sdsfasdqe') value
O:oracle 没发现,但是 instr 可以通过第四个参数控制出现次数
select INSTR('sdsfasdqe','sd',1,2) value from dual 返回 6
24. 求子串
S:select substring('abcd',2,2) value
O:select substr('abcd',2,2) value from dual
25. 子串代替 返回 aijklmnef
S:SELECT STUFF('abcdef', 2, 3, 'ijklmn') value
O:SELECT Replace('abcdef', 'bcd', 'ijklmn') value from dual
26. 子串全部替换
S: 没发现
O:select Translate('fasdbfasegas','fa',' 我 ' ) value from dual
27. 长度
S:len,datalength
O:length
28. 大小写转换 lower,upper
29. 单词首字母大写
S: 没发现
O:select INITCAP('abcd dsaf df') value from dual
30. 左补空格( LPAD 的第一个参数为空格则同 space 函数)
S:select space(10)+'abcd' value
O:select LPAD('abcd',14) value from dual
31. 右补空格( RPAD 的第一个参数为空格则同 space 函数)
S:select 'abcd'+space(10) value
O:select RPAD('abcd',14) value from dual
32. 删除空格
S:ltrim,rtrim
O:ltrim,rtrim,trim
33. 重复字符串
S:select REPLICATE('abcd',2) value
O: 没发现
34. 发音相似性比较 ( 这两个单词返回值一样,发音相同 )
S:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe')
O:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') from dual
SQLServer 中用 SELECT DIFFERENCE('Smithers', 'Smythers') 比较 soundex 的差
返回 0-4 , 4 为同音, 1 最高
日期函数
35. 系统时间
S:select getdate() value
O:select sysdate value from dual
36. 前后几日
直接与整数相加减
37. 求日期
S:select convert(char(10),getdate(),20) value
O:select trunc(sysdate) value from dual
select to_char(sysdate,'yyyy-mm-dd') value from dual
38. 求时间
S:select convert(char(8),getdate(),108) value
O:select to_char(sysdate,'hh24:mm:ss') value from dual
39. 取日期时间的其他部分
S:DATEPART 和 DATENAME 函数 (第一个参数决定)
O:to_char 函数 第二个参数决定
参数 --------------------------------- 下表需要补充
year yy, yyyy
quarter qq, q ( 季度 )
month mm, m (m O 无效 )
dayofyear dy, y (O 表星期 )
day dd, d (d O 无效 )
week wk, ww (wk O 无效 )
weekday dw (O 不清楚 )
Hour hh,hh12,hh24 (hh12,hh24 S 无效 )
minute mi, n (n O 无效 )
second ss, s (s O 无效 )
millisecond ms (O 无效 )
----------------------------------------------
40. 当月最后一天
S: 不知道
O:select LAST_DAY(sysdate) value from dual
41. 本星期的某一天(比如星期日)
S: 不知道
O:SELECT Next_day(sysdate,7) vaule FROM DUAL;
42. 字符串转时间
S: 可以直接转或者 select cast('2004-09-08'as datetime) value
O:SELECT To_date('2004-01-05 22:09:38','yyyy-mm-dd hh24-mi-ss') vaule FROM DUAL;
43. 求两日期某一部分的差(比如秒)
S:select datediff(ss,getdate(),getdate()+12.3) value
O: 直接用两个日期相减(比如 d1-d2=12.3 )
SELECT (d1-d2)*24*60*60 vaule FROM DUAL;
44. 根据差值求新的日期(比如分钟)
S:select dateadd(mi,8,getdate()) value
O:SELECT sysdate+8/60/24 vaule FROM DUAL;
45. 求不同时区时间
S: 不知道
O:SELECT New_time(sysdate,'ydt','gmt' ) vaule FROM DUAL;
----- 时区参数 , 北京在东 8 区应该是 Ydt-------
AST ADT 大西洋标准时间
BST BDT 白令海标准时间
CST CDT 中部标准时间
EST EDT 东部标准时间
GMT 格林尼治标准时间
HST HDT 阿拉斯加 ? 夏威夷标准时间
MST MDT 山区标准时间
NST 纽芬兰标准时间
PST PDT 太平洋标准时间
YST YDT YUKON 标准时间
移至常见问题
一、数据库环境从oracle 转向mysql 碰到的问题。
因为逻辑不变,所以原则是不改应用程序代码,只改数据库表的创建/ 初始化sql 。下面是我们碰到的问题以及解决办法。
1 、 大小写敏感的区别( 如果服务器OS 是linux) 。
在oracle 中一般情况下不区分大小写。有时候我们在使用oracle 不注意大小写的问题,表名和字段名不加双引号是不区分大小写的,像这样:insert
into tableName 和 insert into
TABLENAME 效果是一样的,用工具导出创建/ 数据初始化脚本,得到的结果一般表名和字段名转化成了大写。
但在MySQL 中,所使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。数据库对应数据目录中的目录,数据库中的每个表至少对应数据库目录中的一个文件( 也可能是多个,取决于存储引擎) 。因此,使用数据库或表实际上是操纵这些文件( 夹) ,所以使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。在以linux 为内核的操作系统中是大小写敏感的。
解决的办法是把mysql 的数据库名和oracle 的大小写保持一致,表名与应用程序中sql 字符串中的表名保持一致,如果应用程序中字段名用了双引号,那请把sql 中的字段名大小写与双引号里的字符保持一致。如果你的应用程序所引用的表名、字段没有统一大小写,那麻烦就大了。
2 、保留字的区别。
像sql 语言的函数名( 如:inteval ,show) 等是保留字。Oracle 中保留字是可以作为表名和字段名,并且不影响使用,但mysql 中保留字是不能作为表名和字段名,如果使用会报语法错误。
解决办法,把sql 语句中的保留字用‘`’ 符号引起来,这个符号位于键盘的tab 键上面; 如果是字段名还有另外一种方法tablename. 字段名。像这样:insert
into tablename (id, `interval`) value(….. 或insert into tablename (id,
tablename.inteval) value(….. 。
3 、数据类型的区别。
在mysql 中没有像oracle 中的varchar2 、number ,mysql 有与之对应的varchar 、numeric ,当然在oracle中没有mysql 的time 类型。
解决办法是替换。
4 、自动增长类型的区别。
Oracle 有sequence ,mysql 中没有,但有auto_increment 属性。
解决办法是把Oracle 中sequence 转换成使用auto_increment 属性,某些情况可能还有一种办法可以解决问题,新建一个独立的表用来专门记录自动增长型的数据。
5 、索引长度限制的区别。
从MySQL
4.1.2 开始,MyISAM 和InnoDB 表索引长度支持1000 字节,也就是说索引字段的长度不能超过1000 字节,如果超过会报这样的错:ERROR
1071 (42000): Specified key was too long; max key length is 1000
bytes 。如果是UTF-8 编码,相当于333 个字符的长度( 因为UTF8 一个字符占3 个字节) 。Oracle 的索引长度限制比mysql 要宽松得多。
解决的办法就不必要多说了,要么改索引的定义,要么改字段的定义长度。
二、为了数据库的兼容性我们应该注意些什么。
数据库的兼容性应该是数据库设计应该重视的一个问题,因为有时候客户存在已经在用的数据库,并且不希望同时维护两个数据库,这样的话兼容多种数据库还能成为产品的一个卖点。
作到数据库的兼容性关键是遵守标准用法。
1 、 遵守标准用法,尽量不使用某种数据库特有的用法。
如msyql 的‘`’ 符号的用法,
再比如,很多人有这种用法,在使用oracle 开发的时候创建sequence ,往表中插数据之前先SELECT
seq.nextval FROM
DUAL; ,然后把查询得到的值作为value 插入表中,这种用法没法适应没有sequence 的数据库,每个数据库都有自动增长型的用法,如果需要使用就应该完全地使用。
再举个例子,不同的数据库对分页查询作了扩展,postgresql 有offset ,limit ,oracle 就没有。
2 、 避免数据库大小写敏感的问题。
选择数据库表名和字段名采用大写还是小写,并且在数据库的设计和编码过程中完全统一。
3 、 保留字。
要求数据库设计者尽量不使用保留字作表名和字段名。也有很多人有这种用法,在表名和字段名前加‘_’ ,像这样:create table _tablename ( _id integer) 。这样永远不会出现保留字引起的问题
mysql 迁移数据库到 oracle (sql注意问题)的更多相关文章
- 迁移数据库数据到SQL Server 2017
概述 本篇我们将利用DMA一步一步实现SQL Server 的迁移.帮助大家理解现在的SQL Server与新版本的融合问题,同时需要我们做哪些操作来实现新版本的升级或者迁移. SQL Serve ...
- MySQL迁移数据库(mysqldump)
一.导出导入所有数据库的数据 1.导出 mysqldump -u root -p123456 --all-databases > all.sql 2.导入 mysql -u root -p123 ...
- MySQL学习-数据库设计以及sql的进阶语句
1.数据库设计 关系型数据库建议在E-R模型的基础上,我们需要根据产品经理的设计策划,抽取出来模型与关系,制定出表结构,这是项目开始的第一步 在开发中有很多设计数据库的软件,常用的如power des ...
- mysql优化-数据库优化、SQL优化
我有一张表w1000,里面有1000万条数据,这张表结构如下:CREATE TABLE `w1000` ( `id` varchar(36) NOT NULL, `name` varchar(10) ...
- Django在使用Mysql迁移数据库时,会报的错
settings : DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'firstproject', ...
- 通过Oracle sql developer从sqlserver迁移数据到oracle
通过Oracle sql developer工具从sqlserver迁移数据到oracle 序言 一般情况下,sqlserver数据迁移到oracle,我们可以使用ODI来进行.但ODI的安装.配置. ...
- 使用MYSQL命令直接导入导出SQL文件
很多时候,我们的数据开发都会用到很多开发利器,比如powerdesigner, navicat等这些软件,虽然好用,但是要收费,在公司里面是禁止使用盗版软件的,怕罚款各方面的,所以我们也不敢直接在公司 ...
- 使用MYSQL命令直接导入导出SQL文件(转)
参考:http://blog.csdn.net/jiary5201314/article/details/52026816 1.MYSQL中将数据库导出成SQL文件 其实很简单的,就是一条语句就可以了 ...
- 使用navicat premium将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL
有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle. 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面. ...
随机推荐
- 一键SSH连接 = SSH密钥登陆 + WindowsTerminal
本文记录如何利用SSH密钥登录和WindowsTerminal/FluentTerminal实现一键SSH连接 目录 一.在本地生成SSH密钥对 二.在远程主机安装公钥 三.在远程主机打开密钥登陆功能 ...
- The Dos and Don'ts for Ceph for OpenStack
Ceph和OpenStack是一个非常有用和非常受欢迎的组合. 不过,部署Ceph / OpenStack经常会有一些容易避免的缺点 - 我们将帮助你解决它们 使用 show_image_direct ...
- Java 用jxl读取excel并保存到数据库(此方法存在局限,仅限本地电脑操作,放在服务器上的项目,需要把文件上传到服务器,详细信息,见我的别的博客)
项目中涉及到读取excel中的数据,保存到数据库中,用jxl做起来比较简单. 基本的思路: 把excel放到固定盘里,然后前段页面选择文件,把文件的名字传到后台,再利用jxl进行数据读取,把读取到的数 ...
- [原题复现][CISCN 2019 初赛]WEB-Love Math(无参数RCE)[未完结]
简介 原题复现: 考察知识点:无参数命令执行 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 源码审计 代码 1 ...
- CorelDRAW常用工具之橡皮擦工具
很多作图以及设计软件都会自带橡皮擦工具,但对于专业做平面设计的小伙伴来说,普通的橡皮工具肯定是无法满足日常作图需求的,今天来看看CorelDRAW的橡皮擦能玩出什么花样来. 1.擦除对象 CorelD ...
- 用MindManager画思维导图的好处有哪些?
大家都听说过思维导图吧?有没有将这样一种图形思维工具真正运用到我们的日常生活中去呢?是否真的知道思维导图怎么用呢?今天小编就来给大家讲一讲,思维导图怎么用. 老规矩,先给大家讲一讲小编用的软件跟系统, ...
- 适合 Java 新手的开源项目集合——在 GitHub 学编程
作者:HelloGitHub--老荀 当今互联网份额最大的编程语言是哪一个?是 Java!这两年一直有听说 Java 要不行了.在走下坡路了.没错,Java 的确在走下坡路,未来的事情的确不好说,但是 ...
- 移动自动化测试框架--openatx
之前学习并使用appium进行移动端测试,对于使用appium的一些体会与感受是否与我相似 1. appium启动服务和app程序非常慢 2. appium搭建环境较复杂 3. appium必须连接u ...
- 基于gin的golang web开发:docker
Golang天生适合运行在docker容器中,这得益于:Golang的静态编译,当在编译的时候关闭cgo的时候,可以完全不依赖系统环境. 一些基础 测试容器时我们经常需要进入容器查看运行情况,以下命令 ...
- php进阶学习-单例设计模式
什么是单例模式(singleton)? 在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个,同时这个类还必须提供一个访问该类的全局访问点. 单例模式的特点 一个类只有一个实例 私有克隆 ...