功能是已COLUMN1为主键(跟GROUP BY 性质一样),对COLUMN2排倒序。在剃重数据时时常用到。
DB2格式:rownumber() over(partition by column1 order by column2 desc)
ORACLE格式:row_number() over (partition by column1 order by column2 desc)
两者功能完全一样,但是对于汉字排序底层原理不一致,所以两种数据库的汉字排序是不一致的,其他没什么要注意的了。
可以用简单程序(SHELL 用sed替换,JAVA string.replace,C的话自己封装个库,WINDOWS批处理可以在set函数值时:替换 )或者文本器编辑进行简单替换。
ROWNUMER OVER这套东西在叫分析函数去度娘下会出来详细的用法
Oracle 和 DB2的区别如下:1、取前N条记录
Oracle:Select * from TableName where rownum <= N
DB2:Select * from TableName fetch first N rows only
2、取得系统日期
Oracle:Select sysdate from dual
DB2:Select current timestamp from sysibm.sysdummy1
3、空值转换
Oracle:Select productid,loginname,nvl(cur_rate,'0') from TableName
DB2:Select productid,loginname,value(cur_rate,'0') from TableName
Coalesce(cur_rate,'0')
4、类型转换(8版有了to_char,to_date,9版新增了to_number)
Oracle:select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') from dual
DB2:select varchar(current timestamp) from sysibm.sysdummy1
## Oracle数据类型改变函数:to_char()、to_date()、to_number()等;
如果仅仅取年,月,日等,可以用to_char(sysdate, 'YYYY'),to_char('MM') ,to_char('DD')取得。
只取年月日TRUNC(SYSDATE),
取时分秒TO_CHAR(SYSDATE,'HH24:MI:SS')。
##DB2数据类型改变函数:char()、varchar()、int()、date()、time()等;
取得年,月,日等的写法:YEAR(current timestamp),MONTH(current timestamp),DAY(current timestamp),HOUR(current timestamp),MINUTE(current timestamp),SECOND(current timestamp),MICROSECOND(current timestamp),
只取年月日可以用DATE(current timestamp),取时分秒TIME(current timestamp)。
Char()是定长字符串(1-255),varchar()为非定长字符串(1-32672)
日期,时间形态变为字符形态: char(current date),char(current time)
将字符串转换成日期或时间形态:TIMESTAMP('2002-10-2012:00:00'),DATE('2002-10-20'),
DATE('10/20/2002'),TIME('12:00:00')
## 目前DB2 V8也支持to_char和to_date
5、快速清空大表
Oracle:truncate table TableName
DB2:alter table TableName active not logged initially with empty table
6、关于ROWID
Oracle它是由数据库唯一产生的,在程序里可以获得
DB2 v8也有此功能。
7、To_Number
Oracle:select to_number('123') from dual
DB2:select cast('123' as integer) from sysibm.sysdummy1
SELECT CAST ( current time as char(8)) FROMsysibm.sysdummy1
8、创建类似表
Oracle:create table a as select * from b
DB2:create table a like b
CREATE TABLE tab_newAS select col1,col2…FROMtab_old DEFINITION ONLY (8版有效,9版无效)
9、decode方法
Oracle:decode方法(DECODE(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值))或者case语句
DB2中只有CASE表达式
SELECT id ,name ,
CASE
WHEN integer(flag)=0 THEN ‘假’
WHEN integer(flag)=1 THEN ‘真’
ELSE ‘异常’
END
FROM TEST
或者
SELECT id ,name ,
CASE integer(flag)
WHEN 0 THEN ‘假’
WHEN 1 THEN ‘真’
ELSE ‘异常’
END
FROM TEST
10、子查询(8版,9版也支持子查询)
Oracle:直接用子查询
Db2:with语句
WITH a1 AS
(select max(id) as aa1 from test )
select id ,aa1 from test ,a1
11、数据类型
比较大的差别:
Oracle:char 2000
DB2: char 254
Oracle: date datetime
Db2: DATE:日期TIME:时间TIMESTAMP:日期时间
1、数据类型转换函数
整型转字符型
字符串转整形
字符串转浮点型
浮点型转字符串
字符串转日期
字符串转时间戳
日期转字符串
ORACLE
to_char(1)
to_number('1')
to_number('1.1')
to_char(1.1)
to_date('2007-04-26','yyyy-mm-dd')
to_date('2007-04-26 08:08:08','YYYY-MM-DD HH24:MI:SS')
to_char(to_date('2007-04-29','yyyy-mm-dd'),'yyyy-mm-dd')
DB2
char(1)
int('1')
double('1.1')
char(1.1)
date('2007-04-26')
to_date('2007-04-26 08:08:08','YYYY-MM-DD HH24:MI:SS')
char(date('2007-04-29'))
兼容写法
cast(1 as char)
cast('1' as int)
无
无
无
兼容
无
2、Where条件弱类型判断
oracle: where 字符型字段 in (整形) 是允许,DB2不允许
select 'abc' from dual where '1' in (1) 在oracle下可通过
select 'abc' from sysibm.sysdummy1 where '1' in (1) 在DB2下报错
oracle:where 字符型字段=数字型字段 允许,DB2不允许
select 'abc' from dual where '1'=1 在oracle下可通过
select 'abc' from sysibm.sysdummy1 whre '1'=1 在DB2下报错
3、replace关键字
oracle支持,DB2不支持 create or replace语句在DB2下是非法的
4、子查询别名
ORACLE 支持select * from(select 1 from dual) 或者 select * from(select 1 from dual) t
DB2 支持select * from(select 1 from sysibm.sysdummy1) t 或者 select * from(select 1 from sysibm.sysdummy1) as t
固兼容的写法是select * from(子查询) t
5、DATE数据类型的区别
ORACLE中DATE型也是带有时分秒的,但DB2下DATE只是年月日,如'2007-04-28',且可作为字符串直接 *** 作,DB2中要记录时分秒必须采用TIMESTAMP型
一个采用hibernate后常见的兼容问题是:
如果在映射文件中定义了某个字段为Date型
<property name="createTime" type="java.util.Date" >
<column name="CREATE_TIME" length="7" />
</property>
则在DB2下,此字段必须定义为timestamp,而不能定义成DATE,不然会报出字符串右截断的错误
对于DB2来说,在查询条件中可以直接用字符串指定日期或时间戳类型字段的值,例如 where create_date = '2007-04-26' 、where create_timestamp = '2007-04-26 08:08:08' ,无须使用字符串转日期函数
6、分页的处理
如果采用JDBC分页的话,注意rownum在DB2中不受支持,比如从masa_area表中取得area_id最小的10条记录,语句分别如下,注意这里的别名t书写方法
ORACLE: select t.* from (select rownum as r1 ,masa_area.* from masa_area order by area_id) t where t.r1<=10
DB2: select t.* from (select rownumber() over() as r1 ,masa_area.* from masa_area order by area_id) t where t.r1<=10
7、decode函数
decode函数在DB2不被支持,兼容的写法是采用case when
8、NVL函数
nvl写法在DB2不被支持,兼容的写法是采用coalesce
ORACLE: select NVL(f_areaid,'空') from masa_user 等同于 select coalesce(f_areaid,'空',f_areaid) from masa_user
DB2: select coalesce(f_areaid,'空',f_areaid) from masa_user
9、substr的不同
DB2 substr举例如下:
masa_group表的f_groupCode字段定义成VARCHAR(100),所以下面这个语句不会出错,如果是substr(f_groupCode,1,101)就出错了
select * from masa_group where substr(f_groupCode,1,50) = '001006' order by f_groupcode
在DB2下无错,但是
select * from masa_group where substr('001006', 1, 50) = '001006' order by f_groupcode
就报错,说第三个参数超限
这是因为'001006'已经定义为一个长度为6的charater了
数据迁移:1、在DB2数据库中通过以下表查询出表的结构
SELECT
TABNAME TAB, --表英文名称
COLNAME COL, --列名称
CASE
WHEN TYPENAME='VARCHAR' THEN 'VARCHAR2'
WHEN TYPENAME LIKE 'SMALLINT' OR TYPENAME LIKE 'BIGINT' THEN 'INTEGER'
WHEN TYPENAME ='CHARACTER' THEN 'CHAR'
WHEN TYPENAME='DECFLOAT' OR TYPENAME ='DECIMAL' THEN 'NUMBER'
ELSE TYPENAME
END TY
, --数据类型
LENGTH LEN , --列长度
scale S, --精度
CASE
WHEN NULLS='N' THEN '否'
WHEN NULLS='Y' THEN '是'
END N --是否为空
--TY||'('||LEN||')'
FROM
SYSCAT.COLUMNS S
WHERE
LEFT( TABSCHEMA, 3 ) <>'SYS'
/* and s.SCALE <>0*/
ORDER BY
S.TABNAME,
S.COLNO
2、根据表的结构在oracle数据库中建表(脚本见《create_tab_onOracle.sql》)
3、通过编写java程序把数据从DB2导入到oracle数据库中(以下代码思想仅供参考)
3.1、 导入db2jcc_license_cu.jar 、db2jcc.jar 、ojdbc14.jar 三个jar包即可
3.2、 编写三个工具类
此类链接DB2数据库工具类
package com.util
import java.sql.Connection
import java.sql.DriverManager
import java.sql.SQLException
public class ConnectionDB2 {
private static final String URL="jdbc:db2://192.168.0.98:50000/sem"//DB2数据库url
private static final String USER="db2admin" //DB2数据库账号
private static final String PASSWORD="dnhc9988"//DB2数据库密码
static{
try {
Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance()//利用反射注册驱动
} catch (InstantiationException e) {
e.printStackTrace()
} catch (IllegalAccessException e) {
e.printStackTrace()
} catch (ClassNotFoundException e) {
e.printStackTrace()
}
}
public Connection getConnection(){
Connection conn=null
try {
conn=DriverManager.getConnection(URL, USER, PASSWORD)
} catch (SQLException e) {
e.printStackTrace()
}
return conn
}
}
此类链接oracle数据库工具类
package com.util
import java.sql.Connection
import java.sql.DriverManager
import java.sql.SQLException
public class ConnectionDB2 {
private static final String URL="jdbc:db2://192.168.0.98:50000/sem"//DB2数据库url
private static final String USER="db2admin" //DB2数据库账号
private static final String PASSWORD="dnhc9988"//DB2数据库密码
static{
try {
Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance()//利用反射注册驱动
} catch (InstantiationException e) {
e.printStackTrace()
} catch (IllegalAccessException e) {
e.printStackTrace()
} catch (ClassNotFoundException e) {
e.printStackTrace()
}
}
public Connection getConnection(){
Connection conn=null
try {
conn=DriverManager.getConnection(URL, USER, PASSWORD)
} catch (SQLException e) {
e.printStackTrace()
}
return conn
}
}
此类用来关闭数据库连接工具类
package com.util
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException
import java.sql.Statement
public class CloseFunction {
//关闭连接方法,释放资源
public static void closeConnection(Connection conn){
if (conn !=null){
try {
conn.close()
} catch (SQLException e) {
e.printStackTrace()
}
}
}
//关闭执行sql,释放资源
public static void closeExecuteSQL(Statement preparedStatement){
if (preparedStatement !=null){
try {
preparedStatement.close()
} catch (SQLException e) {
e.printStackTrace()
}
}
}
//关闭查询SQL结果,释放资源
public static void closeResultSet(ResultSet resultSet){
if(resultSet !=null){
try {
resultSet.close()
} catch (SQLException e) {
e.printStackTrace()
}
}
}
}
关键在此类:需要从DB2数据库查询语句放在db2SQL变量中,往oracle插入数据的语句放在oracleSQL变量中。注意,查询和插入的语句中字段顺序要一致,在while循环里要对日期时间处理(用setDate),然后执行junit测试类就可以了。
package com.dao
import java.security.interfaces.RSAKey
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException
import java.sql.Statement
import org.junit.Test
import com.util.CloseFunction
import com.util.ConnectionDB2
import com.util.ConnectionOracle
public class FromDB2ToOracle {
@Test
public void test1() throws SQLException{
long startTime=System.currentTimeMillis()//记录开始时间
Connection connDB2=null//链接DB2数据库
Connection connOracle=null//链接oracle数据库
Statement statement=null
ResultSet resultSet=null
PreparedStatement preparedStatement=null
try {
ConnectionOracle connectionOracle=new ConnectionOracle()
// System.out.println(connectionOracle+"链接oracle成功!")
ConnectionDB2 connectionDB2=new ConnectionDB2()
// System.out.println(connectionDB2+"-->>>链接DB2数据库成功!")
connDB2=connectionDB2.getConnection()
//执行DB2数据库sql语句,此处并非固定代码
String
db2SQL="SELECT ID,SENDNO,SENDTYPE,BRNUMBER
,SENDTIME,ALARMTIME,SENDCONTENT,ISSEND ,ELEALARMID from
DB2ADMIN.ET_SENDMESSAGEINFO"
//执行oracle数据库sql语句,此处并非固定代码
//String oracleSQL="INSERT INTO EPC.SYS_LOG(ID,REMARK) values(?,?)"
String
oracleSQL="INSERT INTO
EPC.ET_SENDMESSAGEINFO(ID,SENDNO,SENDTYPE,BRNUMBER
,SENDTIME,ALARMTIME,SENDCONTENT,ISSEND ,ELEALARMID )"
+ "VALUES(?,?,?,?,?,?,?,?,?)"
statement=connDB2.createStatement()
statement.execute(db2SQL)//执行sql语句
resultSet=statement.getResultSet()//获取DB2数据库的结果集
connOracle=connectionOracle.getConnection()//获取oracle数据库连接
connOracle.setAutoCommit(false)//把oracle数据库设置为非自动提交,以免在再循环里每次都提交,减低效率
preparedStatement=connOracle.prepareStatement(oracleSQL)//执行oracle语句,预编译
int num=0
while (resultSet.next()) {
num ++
preparedStatement.setString(1,resultSet.getString("ID"))
preparedStatement.setString(2, resultSet.getString("SENDNO"))
preparedStatement.setString(3, resultSet.getString("SENDTYPE"))
preparedStatement.setString(4, resultSet.getString("BRNUMBER"))
preparedStatement.setDate(5, resultSet.getDate("SENDTIME"))
preparedStatement.setDate(6, resultSet.getDate("ALARMTIME"))
preparedStatement.setString(7, resultSet.getString("SENDCONTENT"))
preparedStatement.setString(8, resultSet.getString("ISSEND"))
preparedStatement.setString(9, resultSet.getString("ELEALARMID"))/*
preparedStatement.setString(10, resultSet.getString("CONSUMETIME"))
preparedStatement.setString(11, resultSet.getString("TASKID"))
preparedStatement.setString(12, resultSet.getString("ISSYNCHRO"))
preparedStatement.setString(13,resultSet.getString("LOGTYPE"))
preparedStatement.setString(14, resultSet.getString("ISCACHE"))
preparedStatement.setString(15, resultSet.getString("LAST_RPORT_TIME"))
preparedStatement.setString(16, resultSet.getString("AUTO_REMEMBER"))
preparedStatement.setString(17, resultSet.getString("REMARK"))*/
preparedStatement.addBatch()
//每一万次在oracle数据库里提交事务
if(num>10000){
preparedStatement.executeBatch()
connOracle.commit()
num=0
}
}
preparedStatement.executeBatch()
connOracle.commit()
} catch (Exception e) {
connOracle.rollback()//oracle数据库事务回滚
e.printStackTrace()
}finally{
new CloseFunction().closeConnection(connOracle)//关闭oracle数据库,释放资源
new CloseFunction().closeConnection(connDB2)//关闭DB2数据库,释放资源
long endTime=System.currentTimeMillis()//记录程序结束时间
System.out.println("总的时间:"+(endTime-startTime)/1000+"秒")
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)