有关从Oracle迁移到PostgreSQL的问题
首先
这是2019年PostgreSQL Advent Calendar的第八天的文章。
这篇文章是我自己在从Oracle迁移到PostgreSQL过程中所调查的内容。
去年开始准备了服务器替换工作(从Windows Server 2008R2 + Oracle 11g 到 Windows Server 2016 + PostgreSQL 9.6),从今年9月开始逐步展开。
最初考虑的是使用 Oracle 12c,但问题主要出在许可费用上(2016年发生了 Oracle Database 许可费的大幅改动)。由于我们有25个地点,成本非常高昂。因此为了降低成本,我们决定转向使用PostgreSQL。
不使用EDB Postgres(与Oracle兼容的高版本PostgreSQL),而是仔细筛选了大约20个现有应用程序的SQL,并从Oracle迁移至PostgreSQL。
PostgreSQL的概述
这个词的发音是“Postgres QL”。它是Ingres的下一版本(Post)并被命名为Postgres。QL是Query Language的缩写。
PostgreSQL采用了追加型架构。即使数据有变化,也不会直接物理删除原始记录,而是添加新行并将原始记录标记为无效。要将未使用的空间重新利用,需要使用VACUUM命令。
将来,EnterpriseDB希望放弃增量式架构,并实施像其他数据库一样拥有UNDO日志的开发中的“zHeap”技术。作为一个数据库,作为一个开放源代码项目,作为一个社区 – 石井達夫先生谈到了PostgreSQL的优势和挑战。
【2021/08/03补充】根据“zheap的现状”,由于zheap的主要开发者Amit离开了EDB,可惜地,“zheap”目前陷入停滞。
支持结束日期 (EOL = 结束生命周期)
【2021/06/25附注】
由于 PostgreSQL 9.6 的支持期限即将到期,我们计划将其升级到某N公司最新支持的 PostgreSQL 12。
【2021/08/02附注】
已撰写一篇关于升级到 PostgreSQL 12 的文章。
更改名称
【2021/08/02更新】
在PostgreSQL 10中,有一些目录名称和函数名称等发生了更改。
-
- ログファイル出力先のディレクトリ名がpg_logからlogへ変更
-
- WALに関連するディレクトリ/関数/コマンドなどでxlogがwal、locationがlsnに変更
- コミットログの出力先ディレクトリ名がpg_clogからpg_xactへ変更
环境
-
- Windows Server 2016
-
- PostgreSQL 9.6
-
- .NETライブラリ「Npgsql」
- psqlodbc ODBCドライバー(UNICODE版)
由于在准备开始时,PostgreSQL 9.6是在还未发布PostgreSQL 10.0之前的版本。
现在已经发布了 PostgreSQL 12(2019/10/3)和 PostgreSQL 13(2020/09/24)。
连接驱动程序已更改为.NET的应用程序使用”Npgsql”,而Classic ASP应用程序(32位)使用psqlodbc(Unicode版本)。
在管理工具的”ODBC数据源管理员(32位)”中注册并使用”PostgreSQL35W PostgreSQL Unicode”作为系统DNS。
由于PostgreSQL OLDDB驱动程序慢且无法正确获取PostgreSQL的numeric类型字段值等问题,因此使用ODBC驱动程序。
不建议使用PostgreSQL的OLEDB连接。
Session("ConnectionString") = "DSN=PostgreSQL35W;Server=localhost;Database=db_test;UID=fuga;PWD=hoge;Port=5432;"
建立
他需要对主机进行设置更改以进行连接。
listen_addresses = '*' # what IP address(es) to listen on;
port = 5432 # (change requires restart)
※更改后,重新启动PostgreSQL服务。
取消评论。将”localhost”更改为”*”。如果不这样做,只能连接到本地主机。
为了从其他主机连接,需要进行以下设置。
设定可以连接的客户端
在pg_hda.conf中添加配置。
允许来自所有客户端电脑的连接。
# IPv4 local connections:
host all all 0.0.0.0/0 md5
限制來自客戶端計算機的連接。
# IPv4 local connections:
host all all 192.168.64.0/24 md5
※認証方式 trust: 可以使用任意角色名无需密码连接,md5: 使用密码认证
※更改后,不需要重新启动PostgreSQL服务
地區
lc_collate和lc_ctype的默认设置是“C”,而lc_messages、lc_monetary、lc_numeric和lc_time将在此次运行中统一设定为“C”。
* 不利的一面是,输出到pg_log的日志消息将不会是日语,而是英语。
按照相同的顺序对照片进行匹配。
如果不设置排序顺序,很容易被忽视,别人会说排序不对。
{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z}
文字コード順
は(清音)
ば(濁音)
ぱ(半濁音)
ハ(清音)
バ(濁音)
パ(半濁音)
{a,A,A,b,B,B,c,C,C,d,D,D,e,E,E,f,F,F,g,G,G,h,H,H,i,I,I,j,J,J,k,K,K,l,L,L,m,M,M,n,N,N,o,O,O,p,P,P,q,Q,Q,r,R,R,s,S,S,t,T,T,u,U,U,v,V,V,w,W,W,x,X,X,y,Y,Y,z,Z,Z}
アイウエオ一つずつ「カタカナ → ひらがな」の順に並びます。
ハ(清音)
は(清音)
バ(濁音)
ば(濁音)
パ(半濁音)
ぱ(半濁音)
更改日志输出设置
将logging_collector从”off”更改为”on”,并将日志输出到pg_log文件夹。
应该设置三个与日志相关的参数以应对故障。
logging_collector = on # Enable capturing of stderr and csvlog
log_line_prefix='[%t] %u %d %p[%l] ' # special values:
※改动后,请重新启动PostgreSQL服务。
[2019-04-25 14:37:08 JST] 7496[1] LOG: database system was shut down at 2019-04-25 14:37:06 JST
[2019-04-25 14:37:08 JST] 7496[2] LOG: MultiXact member wraparound protections are now enabled
[2019-04-25 14:37:08 JST] 6592[3] LOG: database system is ready to accept connections
[2019-04-25 14:37:08 JST] 3240[1] LOG: autovacuum launcher started
【2020/04/03补充】
当发生错误时,知道客户端IP和应用程序会更容易追踪到错误的原因。
%r:输出客户端IP地址
%a:输出应用程序,例如psql pgAdmin III,大部分是未知[unknown]的。
log_line_prefix='[%t] %u %d %p[%l] %r %a ' # special values:
[2020-03-30 17:42:57 JST] hoge test 5912[1] 127.0.0.1(65080) psql ERROR: duplicate key value violates unique constraint "pk_sno"
[2020-03-31 10:26:21 JST] hoge test 4172[1] 10.20.30.1(54228) pgAdmin III- ?????????????????? ERROR: syntax error at or near "elect" at character 1
[2020-03-31 16:21:20 JST] hoge test 7424[1] 192.168.0.105(49160) [unknown] LOG: could not receive data from client: An existing connection was forcibly closed by the remote host.
由于使客户端IP可见,我们能够确定连接被终止的IP地址是本地(127.0.0.1),而不是远程地址。这样我们就能找出问题的原因了。原来,服务器监控软件在300秒超时后会强制断开连接。
省略输入psql密码
要在没有输入密码的情况下执行psql,需要在下面的文件夹中的”pgpass.conf”中设置密码。
%APPDATA%\postgresql\pgpass.conf
localhost:5432:*:postgres:(パスワード)
作为另一种选择,虽然在安全性上不推荐,但可以在批处理文件中设置环境变量(PGPASSWORD)然后运行。
SET PGPASSWORD=(パスワード)
psql -U (ユーザー) -f xxxxx.sql
更改的数据类型,函数
数据类型
在创建表时需要更改的数据类型如下所示。※仅代表个人观点。
DATETIMESTAMPDATEのままだと日付のみになる
SYSDATEcurrent_timestamp
※SQL92に従いnow()は使わない現在の日付/時刻を取得する関数HH24MMSS → HH24MISSROWIDoid32bit(約43億)で一周してしまうCreate文でWITH OIDSと設定しないと使用できない。PostgreSQL12以降はWITH OIDS廃止
请使用以下参照进行Oracle_fdw的数据类型映射。
请留意
Oracle中的VARCHAR2是以字节计算的,而PostgreSQL中的CHARACTER VARYING是以字符计算的。
将Oracle的NUMBER类型直接转换为PostgreSQL的NUMERIC类型存在一些弊端。
如果只能存放整数,可能更好的选择是直接使用smallint类型或integer类型。
在.NET应用程序中,由于类型转换错误导致需要修复程序。
在Oracle中,Number类型仅限整数,因此之前使用(int)进行类型转换,但在PostgreSQL中,NUMERIC类型将转换为Decimal类型,如果在使用DataRow时使用(int)进行类型转换,将会发生类型转换错误。因此,我进行了修正,使用Convert.ToInt32进行类型转换。
参考:当从DataRow中提取值时,无法将其转换为decimal类型。
函数
在创建表时需要更改的函数如下所示。
WHEN cmp_expr1 THEN ret_expr1
WHEN cmp_expr2 THEN ret_expr2
ELSE default_expr ENDexprがcmp_expr1と同値ならret_expr1を返す、cmp_expr2と同値ならret_expr2を返す、それ以外ならdefault_exprを返す。SELECT t1.key1, t1.name1, t2.name2 FROM table t1, table t2 WHERE t1.key1 = t2.key2(+)SELECT t1.key1, t1.name1, t2.name2 FROM table t1 LEFT OUTER JOIN table t2 ON t1.key1 = t2.keyt1の列key1にしか存在しないデータを検索
有关SUBSTR的内容
当第2参数的起始索引为”0″时,在Oracle中与起始索引”1″相同,但在PostgreSQL中会删除前1个字符。
※可以将第2参数的起始索引视为从”1″开始。
[数据库比较]子字符串获取SUBSTR的陷阱
-- Oracle
SELECT SUBSTR('ABCDE',0,3) FROM DUAL -> 'ABC'
-- PostgreSQL
SELECT SUBSTR('ABCDE',0,3) -> 'AB'
如果第二个参数是负数(表示要从右边获取),需要注意。如果想从右边获取,可以使用RIGHT函数。
-- Oracle
SELECT SUBSTR('123456', -4, 4) FROM DUAL -> '3456'
-- PostgreSQL
SELECT SUBSTR('123456',-4, 4) -> null
SELECT RIGHT('123456', 4) -> '3456'
文字串連
当在SELECT语句中连接包含null字符串的列时,整个结果将变为null。
为了避免这种情况,可以为每列指定替代null的字符串。
[PostgreSQL] PostgreSQL中在SELECT语句中连接Null字符串的方法是什么?
SELECT ok_column || '-' || coalesce((null_column, '') FROM foo;
规格
仕様差比功能差更为棘手。
PostgreSQL 企业联盟技术部门第2工作组
从不同种类的 DBMS 迁移到 PostgreSQL 的数据迁移和字符编码转换
链接:https://www.pgecons.org/wp-content/uploads/PGECons/2013/WG2/05_DataMigrationResearch_ConvertCharacterCode.pdf
-
- SQLの観点から「Oracle Database」「PostgreSQL」「MySQL」の特徴を整理しよう!
- OracleからPostgreSQLに乗り換えたい人に送る何か
对于NULL和空字符串的处理
在Oracle中,NULL和空字符串被视为相同的,但在PostgreSQL中则被区分为两个不同的对象。
除法运算会产生误差。
如果SQL内部实现了包含除法运算的计算,答案将不一致。这不是一个错误,而是一种规范。
要么允许误差,要么如果不能容忍误差的话,应该在SQL中只存储计算结果而不进行计算。
交易结果不同
当使用多个事务时,事务的并发执行结果将会不同。
-
- PostgreSQLとOracle Databaseのアーキテクチャ構造
- 日経SYSTEMS 2019/7 特集2 Oracle DB コスト削減大作戦
SQL语句迁移
在中文中,可以这样表达:
表名和列名的大小写区分
没有引号的标识符始终被解释为小写,但通过用引号括起来,可以区分大小写。例如,标识符FOO、foo和”foo”在PostgreSQL中被视为相同,但”Foo”和”FOO”被视为不同的标识符(因为PostgreSQL将没有引号的标识符解释为小写,并不与标准SQL兼容。根据标准SQL,没有引号的标识符应该被解释为大写。因此,根据标准SQL,foo应该与”FOO”相同,与”foo”不同。如果想写一个可移植的应用程序,建议将特定的标识符统一地用引号括起来,或者完全不用引号括起来)。
如果查询条件中使用了表名或列名,由于PostgreSQL将其转换为英文小写,因此需要将英文大写字母转换为小写字母。
文字型的数值比较会出现错误。
在PostgreSQL的情况下,如果在Numeric类型后面加上单引号来指定,会导致错误。
修正示例:KBN=1 → KBN=’1′
在PostgreSQL中,如果没有给1位字符型的varchar类型加上单引号进行指定,就会出现错误。
修正例:KBN=’1′ → KBN=1
文稿格式
在 PostgreSQL 中,to_char/to_number 函数需要指定第2个参数,如果省略则会出错。
迁移到 PostgreSQL
在PostgreSQL中,使用to_char函数会在字符串的开头添加一个半角空格。
通过在to_char函数的第二个参数中添加FM前缀,可以取消自动添加的半角空格。
-- Oracle
SELECT TO_CHAR(10, '00000') FROM DUAL -> '00010'
-- PostgreSQL 先頭の半角スペースが入る
SELECT to_char(10, '00000') -> ' 00010'
-- PostgreSQL
SELECT to_char(10, 'FM00000') -> '00010'
PostgreSQL的數字字串轉換
添加DUAL表
Oracle有一个DUAL表,但是PostgreSQL没有。
在PostgreSQL中不需要写FROM。
DUAL表在Oracle中的语源是什么?
-- Oracle
SELECT '' FROM DUAL
-- PostgreSQL
SELECT ''
通过创建DUAL表,以便在迁移操作中不会遇到困难,使其与Oracle表现相同。
CREATE TABLE DUAL (
DUMMY CHARACTER VARYING(1) DEFAULT '1' NOT NULL
)
WITH (
OIDS=FALSE
);
-- OWNER設定
ALTER TABLE DUAL
OWNER TO postgres;
【2021/09/08追加】
与其创建表格,将其作为视图更为常见。
PostgreSQL与Oracle之间的数据库互迁手册 – ThinkIT
CREATE VIEW dual AS
SELECT 'X' AS DUMMY;
指定结果集中的行号
-- Oracle
SELECT * FROM 商品マスタ
WHERE 卸単価 IS NOT NULL
AND ROWNUM <= 5
ORDER BY 卸単価 DESC;
-- PostgreSQL
SELECT * FROM 商品マスタ
WHERE 卸単価 IS NOT NULL
ORDER BY 卸単価 DESC
LIMIT 5 OFFSET 0;
外部连接(Outer Join)语法
次の言葉を中国語で自然な表現に言い換えると、一つのオプションがあります:
副问题查询
在Scala子查询的情况下,Oracle和PostgreSQL的语法不会有变化。但是,在使用FROM子句或WHERE子句时,PostgreSQL需要使用别名。
标量子查询
没有区别
SELECT 商品名 FROM 商品マスタ
WHERE 卸単価 = (SELECT MAX(卸単価) FROM 商品マスタ);
在从句中进行副问句的查询方式。
如果在PostgreSQL中没有为子查询添加别名(例如T),则会出现错误。
-- Oracle
SELECT 担当者名
FROM (SELECT *
FROM 担当者マスタ
WHERE 生年月日< '1970-1-1')
WHERE MGR_ID IS NOT NULL;
-- PostgreSQL
SELECT 担当者名
FROM (SELECT *
FROM 担当者マスタ
WHERE 生年月日< '1970-1-1') T
WHERE MGR_ID IS NOT NULL;
在DELETE语句的FROM子句中不能使用JOIN
将句子”USING”改为”使用”或”利用”句子,将”IN”改为”在”句子。
合并文档支持(PostgreSQL 15及更高版本)。
PostgreSQL 15现已支持MERGE语句。
-
- PostgreSQL15 検証レポート – pdf
- PostgreSQL 15にMERGE文UPSERTがやってくる
集合演算 (jí hé 的意思是对集合元素进行操作和计算的一种数学过程。
在UNION和INTERSECT语句中没有任何更改。然而,在Oracle中的MINUS子句在PostgreSQL中被改为EXCEPT子句。
※由于在性能验证时EXCEPT子句较慢,因此我们经常将其改写为NOT EXISTS。这并不仅仅是简单的转换。
-- Oracle
SELECT 担当者ID, 担当者名
FROM 担当者マスタ
MINUS
SELECT 支店担当者ID, 支店担当者名
FROM 支店担当者マスタ
ORDER BY 1;
-- PostgreSQL
SELECT 担当者ID, 担当者名
FROM 担当者マスタ
EXCEPT
SELECT 支店担当者ID, 支店担当者名
FROM 支店担当者マスタ
ORDER BY 1;
複合索引的指定方式
进行性能验证时,其中一个原因是它很慢。
对于包含从索引定义的第一列开始的任意数量连续向右的列的查询,可以使用多列索引。
11.3. 多列索引。
由于复合索引只在连续指定的列中有效,所以如果从索引定义的中间列开始指定条件,索引将失效并变慢。
WHERE AC = xxx AND AD = xxx
↓
WHERE AA = xxx AND AB = xxx AND AC = xxx AND AD = xxx
与Oracle的不同
对于Oracle来说,自从Oracle 9i开始,即使索引中的第一列不包含在提取条件中,也可以通过跳过第一列来使用复合索引的INDEX (SKIP SCAN)功能。然而,由于PostgreSQL目前还没有这个功能,所以必须始终使用索引,就必须确保提供了第一个键。
考虑一个表格的列(C1、C2、C3)现在正在使用复合索引来进行排序。这个复合索引是根据C1、C2和C3的顺序进行排列的。复合索引是指定构成列中的哪一列来选择候选项。
複合インデックス利用可不可PostgreSQL
複合インデックス利用可不可○○○可可○○×可可○××可可○×○可 ※C1のみ、C3は無視可 ※C1のみ、C3は無視×○○可 ※索引スキップ・スキャン可 ※table scanが選択される可能性高い×○×可 ※索引スキップ・スキャン可 ※table scanが選択される可能性高い××○可 ※索引スキップ・スキャン可 ※table scanが選択される可能性高い×××不可不可
使用bloom索引
当主键有多个时,索引默认使用b-tree索引,但弱点是当首个键不匹配时,索引将无法被使用。如果遇到这种情况,可以通过使用布隆过滤器索引,即使首个键条件不匹配,索引仍然可以被使用。
无法创建连接的索引
在PostgreSQL中,当使用双竖线连接列时,索引将失效。
在Oracle中,可以创建双竖线连接的索引本身,但在PostgreSQL中不可以。
在PostgreSQL中,可以通过创建单个或复合索引,并使用行值表达式来使索引生效。
不能将日期和时间分开进行比较。
SELECT * FROM TEST
WHERE
(UPDATE_DATE, UPDATE_TIME) > ('20190218','141435') AND
(UPDATE_DATE, UPDATE_TIME) <= ('20190219','141435')
尽管Oracle的行值表达式只支持等于(=,!=,IN)运算符,但PostgreSQL还支持范围条件(>,<=等)。需要注意的是,SQLServer至今仍不支持行值表达式。
用户定义函数 hù shù)
NVL函数
移植Oracle的NVL函数到Postgres的Coalesce函数失败了。
-- 型違いの複数登録が必要
CREATE OR REPLACE FUNCTION nvl(expr1 text, expr2 text)
RETURNS text AS
$BODY$
SELECT coalesce($1, $2);
$BODY$
LANGUAGE sql;
CREATE OR REPLACE FUNCTION nvl(expr1 date, expr2 date)
RETURNS date AS
$BODY$
SELECT coalesce($1, $2);
$BODY$
LANGUAGE sql;
CREATE OR REPLACE FUNCTION nvl(expr1 numeric, expr2 integer)
RETURNS numeric AS
$BODY$
SELECT coalesce($1, $2);
$BODY$
LANGUAGE sql;
日期计算、时间计算
在PostgreSQL中,由于没有提供ADD_MONTHS等日期计算和时间计算函数,所以最好是使用用户自定义函数来创建所需功能。
在使用PostgreSQL进行日期计算和时间计算时,可以使用interval类型,例如’1 month’等等。
CREATE FUNCTION add_months(in timestamptz, in int4)
RETURNS timestamptz AS
$BODY$
SELECT $1 + $2 * interval '1 month'
$BODY$
LANGUAGE 'sql'
动态查询
以「EXECUTE sql;」的方式执行动态查询。并以「RETURN QUERY」的方式返回表格。
PostgreSQL备注- 存储过程
CREATE FUNCTION func_FugaTable(key text)
RETURNS TABLE(col1 text, col2 text) AS $$
DECLARE
sql TEXT;
BEGIN
sql := 'SELECT id::text, name::text FROM t_Fuga WHERE id = ''' || key || '''';
RETURN QUERY EXECUTE sql;
END;
$$ LANGUAGE plpgsql;
三角函数
-
- Oracleではトリガー単体ですんだが、PostgreSQLではトリガーとトリガー専用関数のセットとなっている。
-
- Oracle は IN、OUT、INOUT というパラメータを関数に渡すことができ、PostgreSQLは IN のみとなっている。
-
- 35.11. Oracle PL/SQLからの移植
- PostgreSQLではTRIGGERのREPLACEが存在しないため、更新の際はTRIGGERの削除が必要になる。
介绍创建和调用三角函数的方法。
-- Insert Beforeトリガ
CREATE OR REPLACE TRIGGER TBI_MSTW000010
BEFORE INSERT
ON MSTW012010
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
:new.CA := TO_CHAR(SYSDATE,'YYYYMMDD');
:new.CB := TO_CHAR(SYSDATE,'HH24MMSS');
END;
-- Update Beforeトリガ
CREATE OR REPLACE TRIGGER TBU_MSTW000010
BEFORE UPDATE
ON MSTW000010
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
:new.CC := TO_CHAR(SYSDATE,'YYYYMMDD');
:new.CD := TO_CHAR(SYSDATE,'HHMMSS');
END;
在PostgreSQL中,需要单独创建一个只用于触发器的函数(无参数)。
-- トリガ関数
CREATE OR REPLACE FUNCTION db_test."MSTW000010_insert"() RETURNS trigger AS
$BODY$
BEGIN
NEW.CA := to_char(current_timestamp,'YYYYMMDD');
NEW.CB := to_char(current_timestamp,'HH24MISS');
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION db_test."MSTW000010_insert"()
OWNER TO postgres;
CREATE OR REPLACE FUNCTION db_test."MSTW000010_update"() RETURNS trigger AS
$BODY$
BEGIN
NEW.CC := to_char(current_timestamp,'YYYYMMDD');
NEW.CD := to_char(current_timestamp,'HHMISS');
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION db_test."MSTW000010_update"()
OWNER TO postgres;
-- Insert Before トリガ
CREATE TRIGGER "TBI_MSTW000010"
BEFORE INSERT
ON db_test.mstw000010
FOR EACH ROW
EXECUTE PROCEDURE db_test."MSTW000010_insert"();
-- Update Before トリガ
CREATE TRIGGER "TBU_MSTW000010"
BEFORE UPDATE
ON db_test.mstw000010
FOR EACH ROW
EXECUTE PROCEDURE db_test."MSTW000010_update"();
自我约束型交易
自律型交易是由正在进行的主要交易启动的独立(自主)交易。主要交易和自律型交易的提交回滚操作互不影响,完全独立的不同交易。
Oracle可以使用自动事务,但是PostgreSQL不能使用。
通过使用dblink等工具可以实现这一功能。
【PostgreSQL】可以在SELECT中更新其他表。
其他(唯一的选择)
-
- PostgreSQLの場合、テーブルのカラム名に予約語(例 “DO”)があるとそのままでは使えない。二重引用符”do”を付与すれば使える
-
- PostgreSQLの場合、SELECTで別名にしたカラム名をORDER BY句で指定できないため、一段上にSELECTを追加する必要がある
-
- PostgreSQLの場合、MAX値取得でORDER BY句があるとエラーになる。そもそもORDER BY句が不要
-
- PostgreSQLの場合、FORMAT関数ではパーセント(%)をエスケープで2つ(%%)にする必要がある
- PostgreSQLの場合、FROMとテーブル名の区切りが全角空白だとエラーになるので半角空白にする。
PL/SQL迁移
将PL/SQL迁移到PostgreSQL-迁移概述/迁移示例。
Oracle到PostgresSQL的迁移工具
转移支援工具(ora2pg)。
-
- ora2pg
-
- このora2pgがすごい!Oracleのストアドプロシージャ2種をPostgreSQLに移行してみた!
-
- how to install ora2pg on windows 7?
-
- OracleからPostgresqlへ移行する
- オープンソースミドルウェアへの移行のための 移植開発支援ツールの評価 pdf
要运行ora2pg,需要使用Perl5。
- Windows で使用できるフリーの Perl実行環境 Strawberry Perl
甲骨文互換函式庫(oraface)。
只要从源代码编译,门槛就会很高(因为有用户提供预编译版本,可以享受到好处),有起初就可使用的环境就很便利。
-
- Orafce ホームページへようこそ
-
- PGECons 組み込み関数移行調査編
-
- orafce拡張モジュールの紹介
-
- PostgreSQL 10、11、および12用のorafce3.8用のプリコンパイル済みライブラリ
- Windows 10 + PostgreSQL 10.10 に orafce を組込む
数据库语法差异
这是由NTT开发的开源工具。它支持Ora2Pg不支持的SELECT语句、UPDATE语句等数据操作的SQL。它还可以用于嵌入在程序语言中作为字符串字面量的SQL代码。然而,实际的修正仍然需要人工进行。
-
- APをPostgreSQLへ移植する際の影響箇所を検出するツール
-
- 影響箇所抽出作業の短縮化
- 抽出の網羅性向上、品質の均⼀化
EDB Postgres(兼容Oracle的高度互換性的PostgreSQL)
EDB Postgres(一个前身是Postgres Plus Advanced Server的产品)具有与Oracle Database高度兼容的特性,支持与Oracle Database相同的SQL语法、函数和过程。
対応トランザクション内のROLLBACK挙動・対応不可Oracle互換モードを選択可能FROM句内のサブクエリで別名不要・FROM句内サブクエリの別名必須対応集合演算子 minus・集合演算子 except対応NULLと空文字の区別がない対応不可一部互換動作を設定可能・ROWNUM
・MERGE文
・oidまたはROWNUMで対応(制限あり)
・INSERT ・・・ON CONFRICT
以下提供了兼容性实用工具。
-
- PostgresPlus Advanced Server の Oracle Database 互換機能検証 – SlideShare
-
- Vol.3 Postgres Plus Advanced Server(体験編1)
-
- Vol.4 Postgres Plus Advanced Server(体験編2)
-
- 商用DBからPostgreSQLへ まず知っておいて欲しいまとめ – SlideShare
- Oratopostgres-hiroshima – SlideShare
请根据以下内容进行中国本土化的改写:
借鉴
-
- PostgreSQL select で文字列を連結するときの注意点
-
- PostgreSQLで文字列の結合(||)をすると勝手にトリムされる(固定長文字列を生成する際には注意)
-
- PostgreSQLとOracleによるデータベース相互移行マニュアル
-
- Oracle PL/SQL からの移植
-
- Oracle DatabaseとPostgreSQLの違い
-
- OracleとPostgreSQLの違い PostgreSQLでは、nullと空文字は区別されます。
-
- [Oracle][PostgreSQL]Date型の違い
-
- Oracle PL/SQL から PostgreSQL PL/pgSQL への移植の注意メモ PostgreSQL では関数をオーバーロードすることができます。
-
- PostgreSQL の SELECT句で Null文字列を連結する方法
-
- PostgreSQLのSQL
-
- PostgreSQLでカラムを追加する際にdefault値を設定する方法
-
- PostgreSQLで自動的にインデックスが生成される条件
-
- PostgreSQLとMySQLはどちらかに明確な優位性がありますか、というの質問・回答
-
- テーブル名やカラム名にSQLの予約語を使う方法
-
- Oracle⇔Postgresqlの組み込みデータ型対応表
-
- PostgreSQLチューニング実践テクニック(DISTINCTよりGROUP BYの方が速い)
-
- PostgreSQL Internals (1) for PostgreSQL 9.6 (Japanese) – SlideShare
- WHERE句でエイリアスを使う
最后
还有其他的机会来谈论关于导入、导出、调整和备份与恢复等等的事项。我在另一篇文章中进行了描述,现在提供链接。
-
- エクスポートやインポート
-
- チューニング
-
- 【PostgreSQL 9.6】指定した時間までリカバリするPITR
-
- 【PostgreSQL 12】指定した時間までリカバリするPITR
-
- 【PostgreSQL】WSH/VBScriptでpsqlを使用する
-
- 【PostgreSQL】psqlのCOPYコマンドに変数で絶対パスを渡す
-
- 【PostgreSQL】psqlのCOPYコマンドによるCSVインポートで重複エラーを回避する
-
- 【PostgreSQL】テーブルのインデックスが壊れた話
-
- PostgreSQLテーブルの作成日時と更新日時の取得について
-
- PostgreSQLインデックスの作成日時と更新日時の取得について
-
- 【PostgreSQL】psqlのスクリプトエラーを無視し続行させる
-
- 【PostgreSQL】SELECT内で他のテーブルを更新する
-
- 【PostgreSQL】トリガーを使用して回数チェックし例外エラーとする
-
- 【PostgreSQL】初回クエリーが遅い
-
- 【PostgreSQL 9.6→12】pg_upgrade によるアップグレード手順
- 【PostgreSQL 12→14】pg_upgrade によるアップグレード手順