怎样将postgresql数据迁移到oracle中
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样将postgresql数据迁移到oracle中相关的知识,希望对你有一定的参考价值。
参考技术A 迁移PostgreSQL到Oracle涉及到两方面工作:表结构的迁移和表数据的迁移。表结构的迁移
表结构的迁移相对简单可以借助ESF DatabaseMigration Toolkit进行.。ESF Database MigrationTookit工具是试用版,所以不能通过其迁移数据(它会将所有varchar字段的开头替换为T)。通过ESF DatabaseMigration Toolkit迁移完成后,通过PL/SQL developer的export userobjects得到创建表结构的语句。
表数据的迁移
数据迁移有2种方式:postgreSQL导出insert语句然后执行语句导入或者postgreSQL导出文件然后用oracle的sqlldr方式导入。前者存在clob难以插入以及sql长度限制等问题,推荐后者方式进行数据迁移。
1.Copy命令导出数据文件
copy table1 to'd:/table1.data' delimiter as '|' nullas '';
注意:postgreSQL存在boolean类型导出为t或者f(oracle用int类型1或者2来代替),使用cast函数
Copy (select cast(column asint) from table1 )to 'd:/table1.data' delimiter as '|' null as '';
批量执行使用sql函数进行
create functionexportLiferay(path text) returns void
as
$$
begin
execute 'copy table1 to ''' || path || 'table1_.data''delimiter as ''|'' null as '''' ';
return;
end;
$$
languageplpgsql;
2. 制作sqlldr控制文件
注意:字符集、clob以及时间,日期类型
load data
CHARACTERSET UTF8
into table table1
fields terminated by "|"
optionally enclosed by '"'
trailing nullcols
(
folderid,
groupid,
companyid,
userid,
createdatetimestamp"yyyy-mm-dd hh24:mi:ss.ff",
modifieddatetimestamp"yyyy-mm-dd hh24:mi:ss.ff",
parentfolderid,
name,
descriptionchar(10000)
)
3.执行导入
sqlldr import/import data=table1.data control=table1.ctllog=table1.log readsize=100000000
注意:根据实际情况,调整readsize本回答被提问者和网友采纳
数据库从 PostgreSQL 迁移到 Oracle
【中文标题】数据库从 PostgreSQL 迁移到 Oracle【英文标题】:Database migration from PostgreSQL to Oracle 【发布时间】:2013-10-02 10:49:52 【问题描述】:我正在将我的数据库服务器从 PostgreSQL 迁移到 Oracle 11g。我尝试了各种工具,例如Squirrel SQL。但是大多数迁移工具都支持表和视图的迁移。我找不到迁移我的过程和功能的解决方案。我可以迁移功能和程序的方式是什么。请找到以下功能之一。
CREATE OR REPLACE FUNCTION hrms.fngetstatus(iactdate character varying, ideactdate character varying)
RETURNS character varying AS
$BODY$
returnval VARCHAR (1);
BEGIN
IF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') IS NULL
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') IS NULL
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') =
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') =
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (ideactdate, 'mm/dd/yyyy') >=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (iactdate, 'mm/dd/yyyy') is null
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
END IF;
RETURN returnval;
END$BODY$
LANGUAGE edbspl VOLATILE SECURITY DEFINER
COST 100;
ALTER FUNCTION hrms.fngetstatus(character varying, character varying)
OWNER TO enterprisedb;
【问题讨论】:
不同的数据库引擎做不同的事情。例如,oracle 没有您在许多其他数据库引擎中找到的两个常用日期函数(dateadd、datediff)。我认为唯一能做到这一点的方法就是手动完成,这样你就可以测试你所做的一切。 你能给我一份文档,我可以在其中阅读清单以在手动转换它们时牢记吗? 你为什么不把它们全部重写。 Oracle 支持来自 Postgress 的不同内置函数 @DanBracuk:您不需要 Oracle(或 Postgres)中笨拙的dateadd
或 dateadd
,因为它支持 ANSI SQL 日期算术,例如some_date + interval '1' week
或者更简单的 current_date + 1
表示“明天”
我粘贴的函数只是一个例子。我尝试直接在 oracle sql 控制台执行此操作,在控制台中出现很多错误。前任。 ORA-06550: line 7, column 24: PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: * & = - + ; < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset member submultiset
【参考方案1】:
您唯一需要更改的是“围绕”函数的代码。 Oracle 使用与 Postgres 不同的“标题”。
所以 PL/SQL 中的函数看起来像这样。我只更改了开头的 CREATE OR REPLACE 和最后的 END
之后的部分。
CREATE OR REPLACE FUNCTION fngetstatus(iactdate varchar, ideactdate varchar)
RETURN varchar
AS
returnval VARCHAR (1);
BEGIN
IF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') IS NULL
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') IS NULL
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') =
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') =
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (ideactdate, 'mm/dd/yyyy') >=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (iactdate, 'mm/dd/yyyy') is null
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'A';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
ELSIF TO_DATE (iactdate, 'mm/dd/yyyy') >
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
AND TO_DATE (ideactdate, 'mm/dd/yyyy') <=
TO_DATE (TO_CHAR (SYSDATE, 'mm/dd/yyyy'), 'mm/dd/yyyy')
THEN
returnval := 'D';
END IF;
RETURN returnval;
END;
/
这是一个 SQLFiddle 示例:http://sqlfiddle.com/#!4/94990/2
【讨论】:
我尝试执行您更新的查询。收到以下错误ORA-06550: line 7, column 24: PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: * & = - + ; < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset member submultiset
@Jeyasithar 那么你并没有告诉我们一切。请参阅我的 SQLFiddle 它确实 工作。 Squirrel 是否支持 PL/SQL 定义的 /
终止符?
我在 Eclipse 中使用数据源浏览器插件来执行查询。
@Jeyasithar:对不起,我不使用 Eclipse,所以我无法对此发表评论。但显然它不支持创建 PL/SQL 过程。您应该尝试使用 SQL Developer、SQL*Plus 或任何其他可以使用备用分隔符的工具(因为这就是您所需要的 - 很可能 Eclipse 将所有内容发送到第一个 ;
,因为它无法识别 /
)跨度>
以上是关于怎样将postgresql数据迁移到oracle中的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 在字符串上的 OUTER JOIN (+) - 迁移 PostgreSQL
怎么将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL