PostgreSQL Oracle 兼容性 - connect by 2

本文介绍如何使用PostgreSQL的tablefunc插件中的connectby函数进行树形查询,提供了一个简单的例子来展示其功能,包括使用分支和排序字段的不同结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标签

PostgreSQL , Oracle , 树形查询 , 递归 , connect by , tablefunc , connectby


背景

Oracle connect by语法经常用于有树形关系的记录查询,PostgreSQL使用CTE递归语法,可以实现同样的功能。

《PostgreSQL Oracle 兼容性之 - connect by 高级选项 CONNECT_BY_ISLEAF、SYS_CONNECT_BY_PATH、CONNECT_BY_ISCYCLE、LEVEL》

《PostgreSQL Oracle 兼容性之 - connect by》

本文通过一个更加简单的方法,同样可以实现一样的功能,用到tablefunc插件中的connectby函数。

接口如下

https://www.postgresql.org/docs/devel/static/tablefunc.html

connectby(text relname, text keyid_fld, text parent_keyid_fld  
          [, text orderby_fld ], text start_with, int max_depth  
          [, text branch_delim ])  
  
setof record	  
  
Produces a representation of a hierarchical tree structure  
ParameterDescription
relnameName of the source relation
keyid_fldName of the key field
parent_keyid_fldName of the parent-key field
orderby_fldName of the field to order siblings by (optional)
start_withKey value of the row to start at
max_depthMaximum depth to descend to, or zero for unlimited depth
branch_delimString to separate keys with in branch output (optional)

例子

create extension tablefunc;  
  
CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int);  
  
INSERT INTO connectby_tree VALUES('row1',NULL, 0);  
INSERT INTO connectby_tree VALUES('row2','row1', 0);  
INSERT INTO connectby_tree VALUES('row3','row1', 0);  
INSERT INTO connectby_tree VALUES('row4','row2', 1);  
INSERT INTO connectby_tree VALUES('row5','row2', 0);  
INSERT INTO connectby_tree VALUES('row6','row4', 0);  
INSERT INTO connectby_tree VALUES('row7','row3', 0);  
INSERT INTO connectby_tree VALUES('row8','row6', 0);  
INSERT INTO connectby_tree VALUES('row9','row5', 0);  
  
-- with branch, without orderby_fld (order of results is not guaranteed)  
SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~')  
 AS t(keyid text, parent_keyid text, level int, branch text);  
 keyid | parent_keyid | level |       branch  
-------+--------------+-------+---------------------  
 row2  |              |     0 | row2  
 row4  | row2         |     1 | row2~row4  
 row6  | row4         |     2 | row2~row4~row6  
 row8  | row6         |     3 | row2~row4~row6~row8  
 row5  | row2         |     1 | row2~row5  
 row9  | row5         |     2 | row2~row5~row9  
(6 rows)  
  
-- without branch, without orderby_fld (order of results is not guaranteed)  
SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0)  
 AS t(keyid text, parent_keyid text, level int);  
 keyid | parent_keyid | level  
-------+--------------+-------  
 row2  |              |     0  
 row4  | row2         |     1  
 row6  | row4         |     2  
 row8  | row6         |     3  
 row5  | row2         |     1  
 row9  | row5         |     2  
(6 rows)  
  
-- with branch, with orderby_fld (notice that row5 comes before row4)  
SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')  
 AS t(keyid text, parent_keyid text, level int, branch text, pos int);  
 keyid | parent_keyid | level |       branch        | pos  
-------+--------------+-------+---------------------+-----  
 row2  |              |     0 | row2                |   1  
 row5  | row2         |     1 | row2~row5           |   2  
 row9  | row5         |     2 | row2~row5~row9      |   3  
 row4  | row2         |     1 | row2~row4           |   4  
 row6  | row4         |     2 | row2~row4~row6      |   5  
 row8  | row6         |     3 | row2~row4~row6~row8 |   6  
(6 rows)  
  
-- without branch, with orderby_fld (notice that row5 comes before row4)  
SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0)  
 AS t(keyid text, parent_keyid text, level int, pos int);  
 keyid | parent_keyid | level | pos  
-------+--------------+-------+-----  
 row2  |              |     0 |   1  
 row5  | row2         |     1 |   2  
 row9  | row5         |     2 |   3  
 row4  | row2         |     1 |   4  
 row6  | row4         |     2 |   5  
 row8  | row6         |     3 |   6  
(6 rows)  

参考

《PostgreSQL 家谱、族谱类应用实践 - 图式关系存储与搜索》

《PostgreSQL 递归妙用案例 - 分组数据去重与打散》

《PostgreSQL Oracle 兼容性之 - INDEX SKIP SCAN (递归查询变态优化) 非驱动列索引扫描优化》

《PostgreSQL 图式搜索(graph search)实践 - 百亿级图谱,毫秒响应》

《[未完待续] AgensGraph 图数据库介绍以及 on ECS部署》

《PostgreSQL 实践 - 内容社区(如论坛)图式搜索应用》

《[未完待续] PostgreSQL 图计算》

《小微贷款、天使投资(风控助手)业务数据库设计(图式搜索\图谱分析) - 阿里云RDS PostgreSQL, HybridDB for PostgreSQL最佳实践》

《PostgrSQL 递归SQL的几个应用 - 极客与正常人的思维》

《PostgreSQL 递归查询CASE - 树型路径分组输出》

《金融风控、公安刑侦、社会关系、人脉分析等需求分析与数据库实现 - PostgreSQL图数据库场景应用》

《用PostgreSQL找回618秒逝去的青春 - 递归收敛优化》

《distinct xx和count(distinct xx)的变态递归优化方法 - 索引收敛(skip scan)扫描》

《时序数据合并场景加速分析和实现 - 复合索引,窗口分组查询加速,变态递归加速》

《facebook linkbench 测试PostgreSQL社交关系图谱场景性能》

《PostgreSQL 使用递归SQL 找出数据库对象之间的依赖关系》

《PostgreSQL 递归死循环案例及解法》

《PostgreSQL 递归查询一例 - 资金累加链》

《PostgreSQL Oracle 兼容性之 - WITH 递归 ( connect by )》

《递归优化CASE - group by & distinct tuning case : use WITH RECURSIVE and min() function》

《递归优化CASE - performance tuning case :use cursor\trigger\recursive replace (group by and order by) REDUCE needed blockes scan》

《PostgreSQL 树状数据存储与查询(非递归) - Use ltree extension deal tree-like data type》

<think>嗯,用户想了解如何在openGauss中创建与Oracle兼容的数据库。我需要先回忆一下openGauss的相关知识。openGauss是华为推出的开源关系型数据库,它确实支持兼容Oracle的语法和功能,方便迁移。 首先,用户可能需要知道如何设置兼容性参数。我记得在创建数据库时,可以通过设置DBCOMPATIBILITY参数为'A'来实现对Oracle的语法兼容。例如,CREATE DATABASE时指定这个参数。这点很重要,因为这会影响到SQL语法、数据类型等的处理方式。 然后,可能需要配置一些其他参数,比如nls_date_format来设置日期格式,使其更符合Oracle的习惯。比如将默认的日期格式改为'YYYY-MM-DD HH24:MI:SS'。不过用户需要注意,这些参数可能需要修改postgresql.conf文件,或者使用ALTER SYSTEM命令,之后重启数据库生效。 接下来,用户可能想知道如何迁移现有的Oracle数据。这时候可以建议使用openGauss提供的工具,比如gs_dump和gs_restore,或者第三方工具如ora2pg。这些工具可以帮助转换和迁移数据,但可能需要一些调整。 另外,兼容性方面可能存在的限制也需要提及。例如,虽然设置了兼容模式,但并非所有Oracle的特性都被支持。某些高级功能可能需要应用层调整或使用替代方案。例如,Oracle的PL/SQL和openGauss的PL/pgSQL在语法上有差异,用户需要注意修改存储过程和函数。 还有,用户可能需要了解如何验证兼容性。可以建议在创建数据库后,执行一些Oracle特有的SQL语句,比如使用DUAL表,或者测试日期函数,确认是否能够正常运行。 还要考虑权限问题,创建数据库需要用户具有CREATEDB权限,或者管理员权限。所以,用户可能需要先以管理员身份登录,比如使用omm账户。 最后,可能应该提醒用户参考官方文档,因为不同版本的openGauss可能在兼容性支持上有所不同,确保信息的准确性。同时,建议在迁移前做好充分的测试,以发现潜在的问题并进行调整。 总结一下,回答的结构应该是先说明如何创建数据库时设置兼容性参数,然后配置相关参数,接着介绍迁移工具,提到兼容性限制,最后给出验证方法和注意事项。这样用户能够一步步地操作,同时了解可能遇到的问题和解决方法。</think>在openGauss中创建Oracle兼容数据库的实现方式如下: 1. 创建数据库时指定兼容模式 ```sql CREATE DATABASE oradb WITH DBCOMPATIBILITY = 'A'; -- A表示兼容Oracle模式 ``` 2. 关键配置参数(需在postgresql.conf中设置): ```properties ora_style_conversion = on -- 启用Oracle风格类型转换 enable_upsert_to_merge = on -- 将UPSERT转换为MERGE enable_nestloop = off -- 优化器行为调整 nls_date_format = 'YYYY-MM-DD HH24:MI:SS' -- 日期格式兼容 ``` 3. 数据类型映射示例: - Oracle的`VARCHAR2` → openGauss的`VARCHAR` - Oracle的`NUMBER` → openGauss的`NUMERIC` - Oracle的`DATE` → openGauss的`TIMESTAMP` 4. 重要兼容特性支持: ```sql -- 支持Oracle伪列 SELECT ROWNUM, ROWID FROM table; -- 支持DUAL表 SELECT SYSDATE FROM DUAL; -- 支持Oracle风格函数 SELECT TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS'); ``` 5. 迁移注意事项: - 使用gs_loader工具转换Oracle数据格式 - 通过`dbms_output`包实现Oracle风格的输出 - 对于PL/SQL代码: ```sql CREATE OR REPLACE PROCEDURE oracle_proc AS BEGIN -- 支持Oracle风格的%TYPE声明 DECLARE v_name employees.name%TYPE; BEGIN DBMS_OUTPUT.PUT_LINE('兼容性测试'); END; END; / ``` 6. 验证兼容性: ```sql SELECT * FROM v$version; -- 查看兼容版本信息 EXEC DBMS_OUTPUT.ENABLE(); -- 测试Oracle包支持 ``` 7. 使用限制: - 不支持OracleCONNECT BY层次查询(需改用WITH RECURSIVE) - 闪回查询实现方式不同 - 自动分区管理需要手动配置 建议配合使用openGauss的Data Studio工具进行SQL开发,其提供Oracle语法兼容性检查功能。完整迁移建议参考官方《Oracle兼容性指南》,并通过`gs_check -U omm -i CheckOracleCompat`命令进行兼容性检查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值