共计 7095 个字符,预计需要花费 18 分钟才能阅读完成。
前言
IvorySQL 是一款基于 PostgreSQL 研发的,具备 Oracle 兼容个性的数据库,所以本文次要介绍 IvorySQL 中 Oracle 兼容个性具体案例。
一、零碎参数
(一)compatible_mode
compatible_mode 是 IvorySQL 目前所提供的零碎参数,次要用于示意以后数据库实例兼容模式,其取值有两个,一个是 Oracle,一个是 Postgres,咱们能够在应用时依据本人须要来进行切换(全局或者会话级)。
在全局设定时,咱们须要 initdb 的时候指定 -c 来确定以后数据库实例兼容模式;
./initdb -D ../data -U ivorysql -c oracle
在以后数据库实例的 postgresql.conf 文件中,能够看到以后的兼容模式,如下:
# default configuration for compatibility mode | |
compatible_mode = oracle # postgres, oracle |
会话级设定兼容模式,如下:
ivorysql=# set compatible_mode = oracle; | |
SET | |
ivorysql=# select 1 from dual; | |
?column? | |
---------- | |
1 | |
(1 row) | |
ivorysql=# set compatible_mode = postgres; | |
SET | |
ivorysql=# select 1 from dual; | |
ERROR: relation "dual" does not exist | |
LINE 1: select 1 from dual; |
通过上述后果能够看到以后兼容模式切换前后对伪表的操作后果。
(二)nls_length_semantics
用于指定会话中创立的数据库对象中的 VARCHAR2 和 CHAR 表列、用户定义的对象属性和 PL/SQL 变量的默认长度语义。
注:NCHAR、NVARCHAR2、CLOB 和 NCLOB 列始终基于字符。
以下以创立带有 varchar2 和 nvarchar2 列的表来进行介绍:
Varchar2
ivorysql=# create table test(a varchar2(5)); | |
CREATE TABLE | |
ivorysql=# SET NLS_LENGTH_SEMANTICS TO CHAR; | |
SET | |
ivorysql=# SHOW NLS_LENGTH_SEMANTICS; | |
nls_length_semantics | |
---------------------- | |
char | |
(1 row) | |
ivorysql=# insert into test values ('开源数据库'); | |
INSERT 0 1 | |
ivorysql=# SET NLS_LENGTH_SEMANTICS TO byte; | |
SET | |
ivorysql=# insert into test values ('开源数据库'); | |
ERROR: value too long for type varchar2(5 byte) | |
ivorysql=# insert into test values ('ivory'); | |
INSERT 0 1 |
Nvarchar2
ivorysql=# create table test(a nvarchar2(5)); | |
CREATE TABLE | |
ivorysql=# SET NLS_LENGTH_SEMANTICS TO CHAR; | |
SET | |
ivorysql=# insert into test values ('开源数据库'); | |
INSERT 0 1 | |
ivorysql=# SET NLS_LENGTH_SEMANTICS TO byte; | |
SET | |
ivorysql=# insert into test values ('开源数据库'); | |
INSERT 0 1 | |
ivorysql=# insert into test values ('开源数据库 1'); | |
ERROR: input value too long for type nvarchar2(5) | |
ivorysql=# insert into test values ('ivory'); | |
INSERT 0 1 | |
ivorysql=# insert into test values ('ivorys'); | |
ERROR: input value too long for type nvarchar2(5) |
从上述后果来看,设置成 char 或者 byte,对于 varchar2 列是无效;则对于 nvarchar2 列来说,则只反对 char,这与 Oracle 原参数设置成果是统一的。
二、高级个性
在以后 IvorySQL 的版本中,相对来说高级个性包含了档次查问以及包,档次查问次要反对通过 SQL 来进行汇总统计和剖析应用;包则是兼容个性的一个相对来说高级根底个性,次要是因为零碎包开发都是须要该个性来进行实现的。
(一)档次查问
层级查问是一种容许对分层数据进行操作的 SQL 语句。
1. 语法
{CONNECT BY [ NOCYCLE] [PRIOR] condition [AND [PRIOR] condition]... [START WITH condition] | |
| START WITH condition CONNECT BY [NOCYCLE] [PRIOR] condition [AND [PRIOR] condition]... | |
} |
本示例演示如何调用档次查问相干语法,结构查问后果。
创立一张测试数据表并插入数据:
CREATE TABLE employees( | |
employee_id integer, | |
name varchar(25), | |
manager_id integer); | |
insert into employees values(101, 'Kochhar', 100); | |
insert into employees values(108, 'Greenberg', 101); | |
insert into employees values(109, 'Faviet', 108); | |
insert into employees values(110, 'Chen', 108); | |
insert into employees values(111, 'Sciarra', 108); | |
insert into employees values(112, 'Urman', 108); |
– 根本查问
postgres=# SELECT name, employee_id, manager_id, LEVEL | |
postgres-# FROM employees START WITH employee_id = 101 | |
postgres-# CONNECT BY PRIOR employee_id = manager_id; | |
name | employee_id | manager_id | LEVEL | |
-----------+-------------+------------+------- | |
Kochhar | 101 | 100 | 1 | |
Greenberg | 108 | 101 | 2 | |
Faviet | 109 | 108 | 3 | |
Chen | 110 | 108 | 3 | |
Sciarra | 111 | 108 | 3 | |
Urman | 112 | 108 | 3 | |
(6 rows) |
–SYS_CONNECT_BY_PATH
postgres=# SELECT name "Employee", SYS_CONNECT_BY_PATH(name, '/') "Path" | |
postgres-# FROM employees | |
postgres-# START WITH name = 'Kochhar' | |
postgres-# CONNECT BY PRIOR employee_id = manager_id; | |
Employee | Path | |
-----------+---------------------------- | |
Kochhar | /Kochhar | |
Greenberg | /Kochhar/Greenberg | |
Faviet | /Kochhar/Greenberg/Faviet | |
Chen | /Kochhar/Greenberg/Chen | |
Sciarra | /Kochhar/Greenberg/Sciarra | |
Urman | /Kochhar/Greenberg/Urman | |
(6 rows) |
–order by
postgres=# SELECT name, CONNECT_BY_ROOT employee_id as "Manager", SYS_CONNECT_BY_PATH(name, '/') "Path" | |
postgres-# From Employees START WITH manager_id is not null | |
postgres-# CONNECT BY PRIOR employee_id = manager_id | |
postgres-# ORDER BY employee_id, manager_id; | |
name | Manager | Path | |
-----------+---------+---------------------------- | |
Kochhar | 101 | /Kochhar | |
Greenberg | 101 | /Kochhar/Greenberg | |
Greenberg | 108 | /Greenberg | |
Faviet | 108 | /Greenberg/Faviet | |
Faviet | 109 | /Faviet | |
Faviet | 108 | /Kochhar/Greenberg/Faviet | |
Chen | 108 | /Kochhar/Greenberg/Chen | |
Chen | 110 | /Chen | |
Chen | 108 | /Greenberg/Chen | |
Sciarra | 108 | /Kochhar/Greenberg/Sciarra | |
Sciarra | 111 | /Sciarra | |
Sciarra | 108 | /Greenberg/Sciarra | |
Urman | 112 | /Urman | |
Urman | 108 | /Greenberg/Urman | |
Urman | 108 | /Kochhar/Greenberg/Urman | |
(15 rows) |
–CONNECT_BY_ROOT 和 SYS_CONNECT_BY_PATH
postgres=# SELECT employee_id, manager_id, name, CONNECT_BY_ROOT employee_id as "Manager", SYS_CONNECT_BY_PATH(name, '/') "Path" | |
postgres-# FROM employees | |
postgres-# START WITH manager_id is not null | |
postgres-# CONNECT BY PRIOR employee_id = manager_id | |
postgres-# order by employee_id, manager_id; | |
employee_id | manager_id | name | Manager | Path | |
-------------+------------+-----------+---------+---------------------------- | |
101 | 100 | Kochhar | 101 | /Kochhar | |
108 | 101 | Greenberg | 101 | /Kochhar/Greenberg | |
108 | 101 | Greenberg | 108 | /Greenberg | |
109 | 108 | Faviet | 108 | /Greenberg/Faviet | |
109 | 108 | Faviet | 109 | /Faviet | |
109 | 108 | Faviet | 108 | /Kochhar/Greenberg/Faviet | |
110 | 108 | Chen | 108 | /Kochhar/Greenberg/Chen | |
110 | 108 | Chen | 110 | /Chen | |
110 | 108 | Chen | 108 | /Greenberg/Chen | |
111 | 108 | Sciarra | 108 | /Kochhar/Greenberg/Sciarra | |
111 | 108 | Sciarra | 111 | /Sciarra | |
111 | 108 | Sciarra | 108 | /Greenberg/Sciarra | |
112 | 108 | Urman | 112 | /Urman | |
112 | 108 | Urman | 108 | /Greenberg/Urman | |
112 | 108 | Urman | 108 | /Kochhar/Greenberg/Urman | |
(15 rows) |
目前此性能有以下限度:
- 附加列可用于大多数表达式,如函数调用、CASE 语句和通用表达式,但有局部不受反对的列,如 ROW、TYPECAST、COLLATE、GROUPING 子句等。
- 两个或多个列雷同的状况下,可能须要输入列名,例如:
SELECT CONNECT_BY_ROOT col AS “col1”, CONNECT_BY_ROOT col AS “col2″。
- 不反对间接运算符或“*”。
- 不反对循环检测(Loop detection)。
目前来看,包含伪列、函数等操作的反对还须要增强,心愿后续该性能能够更加丰盛。
(二)包
包简略来说就是一个对象或一组对象打包在一起。将过程、函数、变量、游标、用户定义的记录类型和援用记录的逻辑分组汇合打包在本人外部,在申明包和包体定义后(架构和内容)就能够进行调用。
示例 1 演示如何创立包和包体,并且进行包内函数调用,脚本如下:
– 申明包
postgres=# create or replace package pkg is | |
postgres$# x int; | |
postgres$# | |
postgres$# function tfunc(x int) return int; | |
postgres$# end; | |
postgres$# / | |
CREATE PACKAGE |
– 申明包体
postgres=# create or replace package body pkg is | |
postgres$# | |
postgres$# function tfunc(x int) return int as | |
postgres$# begin | |
postgres$# return x; | |
postgres$# end; | |
postgres$# end; | |
postgres$# / | |
CREATE PACKAGE BODY |
– 能够通过零碎表查看包内成员
postgres=# select proname, proargtypes from pg_proc p, pg_package pk where pronamespace=pk.oid and pkgname='pkg' order by proname; | |
proname | proargtypes | |
---------+------------- | |
pkg | | |
tfunc | 23 | |
(2 rows) |
– 调用包内函数
postgres=# select pkg.tfunc(10); | |
tfunc | |
------- | |
10 | |
(1 row) |
示例 2 演示包内函数和存储过程重载如下:
– 创立包定义
postgres=# create or replace package pkg | |
postgres-# is | |
postgres$# | |
postgres$# function tfunc return int; | |
postgres$# | |
postgres$# procedure tpro; | |
postgres$# | |
postgres$# function tfunc(x int,y int) return int; | |
postgres$# procedure tpro(x int); | |
postgres$# end; | |
postgres$# / | |
CREATE PACKAGE |
– 创立包体
postgres=# create or replace package body pkg | |
postgres-# is | |
postgres$# function tfunc return int | |
postgres$# as | |
postgres$# begin | |
postgres$# return 0; | |
postgres$# end; | |
postgres$# | |
postgres$# procedure tpro | |
postgres$# as | |
postgres$# pvar int; | |
postgres$# begin | |
postgres$# pvar:=10; | |
postgres$# end; | |
postgres$# | |
postgres$# function tfunc(x int,y int) return int | |
postgres$# as | |
postgres$# begin | |
postgres$# return (x+y); | |
postgres$# end; | |
postgres$# | |
postgres$# procedure tpro(x int) | |
postgres$# as | |
postgres$# y int; | |
postgres$# begin | |
postgres$# y := x; | |
postgres$# end; | |
postgres$# end; | |
postgres$# / | |
CREATE PACKAGE BODY |
– 执行函数调用
select pkg.tfunc(); | |
select pkg.tfunc(1,2); |
三、总结
上文介绍并演示了 IvorySQL 的几个兼容个性,作为目前惟一基于 PG 开源的 Oracle 兼容数据库来说,尽管具体性能与原生 Oracle 还有十分大的差距,然而毕竟仍在起步阶段,心愿将来 IvorySQL 能减少更多的兼容个性。
另外,在相干配套工具方面,包含管理工具、数据迁徙、复制等,以及在云相干利用方面提供更多的可用产品。
对于 IvorySQL
IvorySQL 是由瀚高开发,基于 PostgreSQL 的一款具备弱小 Oracle 兼容能力的开源数据库。紧跟 PG 社区,疾速进行版本迭代,放弃与最新版本 PostgreSQL 数据库内核同步,并反对丰盛的 PostgreSQL 周边工具和扩大。
IvorySQL 致力于创立容纳和激情的社区,保持凋谢,自在,共享的精力,放弃专一、专业性。
官网网址:
https://www.ivorysql.org/zh-cn/
社区仓库:
https://github.com/IvorySQL/I…
IvorySQL 社区欢送并赞叹所有类型的奉献,期待您的退出!
还有,别忘了在 GitHub 给咱们一个 ⭐奥~