Oracle 到PG迁移相关记录

Oracle 的VARCHAR2字符编码是: 
NLS_CHARACTERSET = ZHS16GBK

NVARCHAR2字符编码是:
NLS_NCHAR_CHARACTERSET = AL16UTF16

也就是说用了GBK和UNICODE两种字符集,但是从客户端读取的时候,Oracle应该可以自动转为UTF8,(CHAR类型一定是和字符编码绑定的)

Oracle,PG的number,numeric的第一个数字是precision是有效数字,scale是小数点后的位数。

  1. 获得表的所有列名、列类型
  2. 生成查询字符串
  3. ACT_EVT_LOG含有BLOB和NVARCHAR2


 

导入导出时注意:

timestamp , Oracle最大精度是9,PG最大精度是6
number --> numeric
clob --> text
blob --> bytea
nvarchar(n) --> varchar(nx3)
nchar(n)          --> char(nx3)

这个程序的限制是,CLOB和BLOB都不能超过1G,

Oracle timestamp(9)转为PG的timestamp(6)

Oracle的 DATE 对应 PG 的 timestamp(0)),因为PG2ORA导出的Oracle的Date是有时分秒的。

Oracle的 default sys_data 对应 PG default current_timestamp

Oracle的 default SYS_GUID() 对应PG的 default gen_random_uuid()

如果gen_random_uuid()报错,需要在PG命令行执行一下 create extension pgcrypto;

sequence也要和建表语句一起执行,

建表时,先不建索引、主键、外键,但是视图、sequence要建,数据导入后再建索引、主键、外键等约束。

paas脚本中有些创建sequence的sql中,最大值为28位数字,而PG最大支持是9223372036854775807

查看sequence的最后一个数字:
select SEQUENCE_NAME, LAST_NUMBER from user_sequences where SEQUENCE_NAME = 'UV_COMPUTER_ROOM_CODE_SEQ';

校验时,检查每个sequence的的last_number是否相同。

Oracle查询并发连接数v$session

导完数据后,所有sequence的设置,PG要与Oracle相同

Python验证程序注意:

PG和Oracle对应的表都要有索引,而且是同样的索引,oracle和pg都是堆表,可以先导入再建索引。
PG、Oracle各种类型的NULL,用Python返回,为None,因此:
CLOB、CHAR、NUMBER类型为NULL时在CONCAT和||返回为长度为0的字符串,
BLOB和BYTEA判断返回值后,跳过对md5函数的调用。
Oracle中的timestemp(0)和date对应PG中的timestemp(0),
都要用to_char(<col_name>, 'YYYY-MM-DD HH24:MI:SS')

python 传参数:列表 ==> *args 也可以表示可变参数
                          字典 ==> **kwargs 表示一个字典,在函数内kwargs就是一个字典
                 传参的形式,可以是有关键字的形式:myfunc(kw1=‘abc’,kw2=‘123’,kw3=‘haha’)

drop schema migr_test cascade;

create schema migr_test;

ALTER USER benchmarksql SET search_path TO migr_test, public;

ORA2PG 安装:

 rpm -ivh oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
 rpm -ivh oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-jdbc-12.2.0.1.0-1.x86_64.rpm
 rpm -ivh oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
 

Oracle用户A要访问所有用户B的表:
用户B登录,执行: GRANT SELECT ANY TABLE TO B;

gbk中文2个字节,英文1个字节;utf-8中文3个字节,英文1个字节

演练时,发现,PG导入后的数据与Oracle中的数据存在一点差异,主要是Oracle的字段里有^@,但是导入PG后这个字符没有了,网上查了一下,在vim里显示^@的是值为'\0'的字符,值为0x00。

Python中包含元组的列表,可以看做是一个表,这个表和“行”就是一个元组,“列”就是元组的某个元素,可以按照列对行进行排序,使用 sorted函数和operator的itemgetter:
sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
参考:Sorting HOW TO — Python 3.10.1 documentationhttps://docs.python.org/3/howto/sorting.html

字符串比较规则问题,非常重要:
查看Oracle的字符串比较规则:
注意这个与数据库字符编码无关,可以看出我的这个Oracle字符编码是AL16UTF16和ZHS16GBK,与PG的UTF8无法对应。当试图以相同的顺序获取表的列名,或者以字符串为主键的表的数据内容时,不注意会有问题。

具体就是PG在创建数据库时有个属性 lc_collate 应该与这里的NLS_SORT相同,Oracle的BINARY对应PG的lc_collate = “C”,在initdb时设置,或者order by的时候指定某个字符串列的collate,例如:order by c1 collate = “C”,注意collate是修饰它前面的列的,不会修饰许多列。

查看PG数据库的collate:

collate决定了字符串类型排序的规则,值为“C”时表示没有规则,即以字符的二进制值大小为比较规则。

注意创建/初始化PG数据库时注意设置lc_collate与Oracle的NLS_SORT相同,PG数据库的ctype可以设置为zh_CN.utf8,表示使用UTF8编码但是错误提示等使用中文的。

Oracle中的DATE在JDBC中是识别为timestamp,所以在JDBC中,以BIND方式,向Oracle插入DATE类型数据,要用setTimestamp

179       } else if (colDef.type() == Types.TIMESTAMP) {
180         if (value instanceof String)
181             statement.setTimestamp(index, java.sql.Timestamp.valueOf((String)value));
182         return true;
183       } else {
colDef.type() 和 Types.TIMESTAMP 的值参考:
Constant Field Values (Java Platform SE 8 )

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值