INFORMIX迁移到ORACLE
一、库表SQL写法问题
1.DATE字段
Informix中datetime year to second,datetime year to day等,统一改为oralce中的DATE字段。否则会报错:ORA-00907: 缺失右括号。
2.extent size属性
Informix中可以使用extent size 50000 next size 10000 lock mode row来限制建表属性,在oracle中不支持,直接去掉。
3.SQL语句中空行问题
在informix中,建表的语句中,可以允许有空行存在,但是在oracle的语句中,一条完整的语句中,不允许中间出现空白行,否则会报错:SP2-0734: 未知的命令开头。
解决办法是:去掉一条语句中无谓的空行。不同语句间存在空行是正常的。
4.Size,level等保留字段名
在informix中,可以定义一个字段名字为size,在oracle中,size属于保留字,直接使用会报错:ORA-00904: : 标识符无效
解决方法是:在类似于size这样的保留名称的字段名称中,在两边加上双引号即可。即:size-->"size",对应的程序代码,也都需要这样修改,特别需要注意的是,双引号内的字符是大小写敏感的,例如上面的"size",程序中用"SIZE"将操作失败。既然反正要改程序,为了防止后面的冲突,不采取这种修改方法,重新修改字段名。为了方便,我们统一在字段名前加上:db_。例如:size-->db_size, level-->db_level。
这样的字段有:size, level,comment,validate,file,number
5.byte大数据字段
在informix中,大数据使用byte类型,在oralce中,使用的是blob/clob类型(BLOB是纯二进制,CLOB是文本,我们选择使用blob),否则,会报错:ORA-00902: 无效数据类型byte
6.lvarchar大数据字段
在informix中,长点的文本数据使用lvarchar类型,此类型缺省长度是2048,最大长度是32767。在oralce中,没有此种类型,按理说,应该使用clob类型,但如果使用clob时,读写都很不方便。如果改用LONG类型来替换的,读写是方便了,但一个表,只允许存在一个LONG字段。为了方便,将INFORMIX的lvarchar改为ORACLE的varchar,如果lvarchar的长度超过4000的话,直接用4000代替。如果lvarchar的长度小于2048的话,直接用2048代替(ORACLE的字符字段长度最大为char 2000, varchar 4000)
7.数字类型长度问题
在informix中,定义一个字段decimal(3),在插入时,可以超过3位长度的数据,但是在oracle中,插入超过1000时,会报错:ORA-01438: 值大于为此列指定的允许精度。
解决办法是:修改此表的这个字段长度,例如:sessiontimeout decimal(3)改为sessiontimeout decimal(8)。
8.serial/serial8问题
在informix中,可以定义一个序列字段serial/serial8,在oracle中,无此字段,用number(
10)代替。在数据迁移时,直接迁移即可,但是在迁移完数据之后,还需要特殊处理。以下为解决样例。
9.boolean数据字段
在informix中,布尔数据使用boolean类型,在oralce中,没有boolean类型,需要使用number(1)类型代替,否则,会报错:ORA-00902: 无效数据类型
二、程序需要修改的地方
10.INFORMIX与ORACLE兼容原则
修改代码的原则是:
(1)凡是INFORMIX与ORACLE有冲突的地方,能够修改成一致,并且不影响原来的业务逻辑的,则直接修改代码。例如:INFORMIX中是size字段名,在oracle中是db_size字段名。那么,INFORMIX中也修改为db_size。
(2)对于无论如何修改,INFORMIX与ORACLE也不能共处的地方,则新加一段代码,这段新加的代码主要意思是:首先调用一个公用方法,获取当前的数据库类型,如果是oracle,则调用另外的一段新写的代码。否则,仍旧调用原来的代码。例如:数据查询分页问题,检查数据值是否为空问题。
(3)尽可能不使用数据库本身提供的函数。
11.Size,level等保留字段名
这样的字段有:size, level,comment,validate,file,number
需要在这些字段名字前加上“db_”,例如:size-->db_size。包括所有的增删改查语句。
注意:表名:check_jifang_bj,字段名遇到保留名字: level
注意:表名:diangan,字段名遇到保留名字: size
注意:表名:groupcircuit,字段名遇到保留名字: number
注意:表名:groupuser,字段名遇到保留名字: level
注意:表名:guandao_segment,字段名遇到保留名字: size
注意:表名:pm_index,字段名遇到保留名字: level
注意:表名:renshoujing,字段名遇到保留名字: size
注意:表名:user_info_tab,字段名遇到保留名字: comment
12.serial/serial8问题
在informix中,可以定义一个序列字段serial/serial8,在oracle中,无此字段,用number(10)代替。此类型需要再次推敲。
注意:表名:pm_job_execution,字段名: executionid
注意:表名:pm_job_execution_cur,字段名: executionid
13.lvarchar大数据字段
在informix中,长点的文本数据使用lvarchar类型,此类型缺省长度是2048,最大长度是32767。在oralce中,没有此种类型,按理说,应该使用clob类型,但如果使用clob时,读写都很不方便。如果改用LONG类型来替换的,读写是方便了,但一个表,只允许存在一个LONG字段。为了方便,将INFORMIX的lvarchar改为ORACLE的varchar,如果lvarchar的长度超过4000的话,直接用4000代替。如果lvarchar的长度小于2048的话,直接用2048代替。
14.boolean数据字段
在informix中,布尔数据使用boolean类型,在oralce中,没有boolean类型,需要使用number(1)类型代替,否则,会报错:ORA-00902: 无效数据类型。
15.名称超过30字节长度
在informix中,名称长度没有限制,但是,在oracle中,对长度有限制,不能超过30个,报错信息为:ORA-00972: 标识符过长。
解决办法是,缩短名字,包括:表名,字段名,索引名,触发器名,外键名,过程名等
注意:1. 如果是索引的话,只需要修改数据库语句,保证全库唯一,不冲突即可。
2. 如果是表名或字段名的话,那就要改程序了。
例如: create index idx_zhimai_segment_zhimai_branch on xxx。在informix中合法,在oracle中 idx_zhimai_segment_zhimai_branch过长(32个字符了)。
16.查询分页
这块需要重新修改。方法实例如下:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM < 41
)
WHERE RN >= 21
其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。ROWNUM < 41和RN >= 21控制分页查询的每页的范围。
17.byte大数据字段
在oracle中,大数据使用BLOB类型(BLOB是纯二进制,CLOB是文本,我们选择使用blob,
如果有需要使用CLOB的话,再议)。同时,数据读写的方式也要进行修改,不能使用原有的方法读写数据。
参考例子:
// 从数据库读一条二进制内容
public static void loadOneBlob(int id) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String sql = "SELECT img_content FROM test_blob WHERE img_id='" + id + "'";
try {
conn = getConnect();
oracle decimal类型 stmt = ateStatement();
rs = uteQuery(sql);
while (rs.next())
{
Blob blob = rs.getBlob(1);
// 二进制内容的大小
int length = (int) blob.length();
// 缓存的大小
byte[] by = new byte[length];
// 获得输入流(源)
InputStream is = BinaryStream();
// IO知识
is.read(by);
is.close();
String str = new String(by, "GBK");
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(rs, stmt, conn);
}
}
//批量将二进制数据写入数据库中
//1,需要在之前将所有的非二进制字段入库(在这里忽略此步)
//2,然后,再单独通过select获取到blob字段的游标
//3,单个写入blob字段(这里不能批量的)。
//drop table test_blob;
//create table test_blob (img_id varchar(64), img_content blob);
public static void saveStringToBlob(int num) {
Connection conn = null;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论