本部分包含如下章节:
KingbaseES V8.3 和 V8.6 兼容特性概览
本章节包含以下内容:
兼容性开关
模式和对象
SQL语句
PLSQL语言
版本新增能力和变更能力明细
支持的客户端编程接口兼容性
KingbaseES用户可通过设置相关的数据库兼容开关,部分或全部启用Oracle兼容特性。在实际应用中,用户可采用以下途径设置Oracle兼容开关:
在数据库实例data目录下的kingbase.conf文件中配置
在数据库初始化时设置
在用户会话中设置
KingbaseES提供了多个Oracle特性兼容开关。在Oracle移植过程中,用户可按需使用这些开关。下表列出KingbaseES提供的Oracle兼容特性开关。
兼容特性开关 |
V8R6 |
V8.3 |
用途说明 |
---|---|---|---|
char_default_type |
不支持 ( oracle兼容模 式下默认就是兼 容类型的设置) |
支持 |
设置字符串类 型的长度单位(char 或byte),它和 Oracle参数 NLS_LENGTH_SEMATICS 的含义 一致(会话级 参数,缺省值是 char)。 |
ora_func_style |
不支持 ( oracle兼容模 式下默认就是兼 容类型的设置) 移植时人为去掉设置该参数的sql |
支持 |
开关开启时兼容oracle 函数及sequence 序列(会 话级参数,缺省 值是true)。 |
default_with_oids |
支持 |
支持 |
开 关开启时,新创 建的表将包含OID 伪列。此 外,如果创建的 表没有OID伪列, 那么这个表也没 有ROWID伪列。如 果创建加密表时 ,必须指定WITH OID。 |
ora_input_emptystr_isnull |
支持 |
支持 |
开 关开启时,系统 将输入的空串当 做NULL处理会 话级参数,缺省 值是true)。 |
ora_date_style |
支持(KingbaseES 使用此开关设 置date数据类型格式时,需要先 打开ora_style_nls_date_format 开关,且ora_date_style默认时间 格式为' YYYY-MM-DD HH24:mi:ss) |
支持 |
开关开启时, date类型的输出 格式兼容oracle date类型输 入格式(会话 级参数,缺省值 是false)。 |
ora_format_style |
不 支持(可以使用Oracle 模式替代) 移植时人为去掉设置该参数的sql |
支持 |
开关开启时 ,格式化输出( to_char,to_time stamp...)兼容 oracle(会话 级参数,缺省值 是false)。 |
nls_timestamp_format |
不支持 |
支持 |
开关开启时,time stamp类型to_char 默认输出格式 兼容oracle会 话级参数,缺省 值是YYYY-MM-DD HH:MI:SS)。 |
nls_length_semantics |
支持 |
不支持 |
设置字符 串类型的长度单位 (char或byte), 它和Oracle参数 NLS_LENGTH_SEMATICS 的含义一致( 会话级参数, 缺省值是char) |
ora_numop_style |
不支持 |
支持 |
开关开启时, integers 操作符当做 numeric操作符。 |
extra_float_digits |
支 持(默认值为1) |
支 持(默认值为0) |
设置浮点 值显示的位数。 |
本节内容旨在为移植过程的相关模式修改操作提供参考指南。
2.1.2.1. 扩展数据类型
为兼容Oracle的数据类型,KingbaseES扩展了Oracle的NUMBER、VARCHAR2、CHAR(n)和DATE类型。该措施使得移植Oracle的Create Table等DDL语句时,无需任何修改就能直接在KingbaseES环境中运行。
下面各表对比了KingbaseES和Oracle在各种数据类型上的异同点。
数据类型名 |
KingbaseES V8R6 |
KingbaseES V8.3 |
---|---|---|
bool |
不支持bool到text的隐 式转换, (比如like 等操作需要此隐式转 换,可修改应用增加显 示转换绕过此问题.) |
支持bool到int的隐式转换 支持bool到text的隐式转 换. |
time,timetz |
不支持 time和timetz到timestamptz 类型的隐式转换(Oracle 中不存在time和timetz 类型,在不影响Oracle 兼容性的基础上保留 了原型的处理逻辑。可 通过修改应用增加显示 转换来绕过此问题。) |
支 持time和timetz到 timestamptz类型 的隐式转换 |
abstime |
不支持 |
内部使用的较低精度类型 |
reltime |
不支持 |
内部使用的较低精度类型 |
tinterval |
不支持 |
支持 |
2.1.2.2. 模式
V8.6 中search_path中的模式名,需要写成小写;
例:
V8.3:
show search_path ; search_path ----------------- "$USER", PUBLIC (1 row)
V8.6 :
show search_path ; search_path ----------------- "$user", public (1 row)
2.1.2.3. 大小写敏感
例:
V8.3:
show case_sensitive ; case_sensitive ---------------- on (1 row)
V8.6 :
show enable_ci ; enable_ci ---------------- on (1 row)
2.1.2.4. 序列
V8.3中select * from sequencename可以得到10列信息, V8.6 直接select * from sequencename只有3列,其余列可通过select * FROM all_sequences WHERE sequence_name=UPPER('sequencename')找到。
例:
V8.3:
CREATE SEQUENCE serial START 1; select * from serial; SEQUENCE_NAME | LAST_VALUE | START_VALUE | INCREMENT_BY | MAX_VALUE | MIN_VALUE | CACHE_VALUE | LOG_CNT | I S_CYCLED | IS_CALLED ---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-- ---------+----------- SERIAL | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 0 | f | f (1 row)
V8.6 :
CREATE SEQUENCE serial START 1; select * from serial ; last_value | log_cnt | is_called ------------+---------+----------- 1 | 0 | f (1 row) select * FROM all_sequences WHERE sequence_name=UPPER('serial'); sequence_owner | sequence_name | min_value | max_value | increment_by | cycle_flag | order_flag | cache_siz e | last_number ----------------+---------------+-----------+---------------------+--------------+------------+------------+---------- --+------------- abcd | SERIAL | 1 | 9223372036854775807 | 1 | f | t | 1 | (1 row)
2.1.2.5. 同义词
V8.6 找同义词时,对于同义词指向的对象,首先依然作为同义词进行递归查找和成环检测,而不是把同义词指向的对象首先按照普通对象查找,这个处理顺序和R3不同。
2.1.2.6. 分区
V8.6 分区支持的兼容V8.3,支持分区的alter,支持全局索引,支持interval分区,不支持reference分区
2.1.2.7. 全局临时表
V8.3支持本地临时表,不支持全局临时表。
V8.6 支持本地临时表和全局临时表。
2.1.2.8. kdb_schedule
目前龙芯平台没有 kdb_schedule 依赖的系统库libboost_system.so.1.69.0, ES安装程序将这个库放到了Server/lib下,使用kdb_schedule之前需要设置export LD_LIBRARY_PATH 中包含Server/lib。
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/Kingbase_install_dir/Server/lib
对于大多数常用的Oracle SQL语句,KingbaseES均提供了原生支持。该措施使得Oracle应用程序移植到KingbaseES系统时,通常只需很少的代码变动。
下面给出KingbaseES中原生支持的Oracle SQL语句。此外,若未做特殊说明,本节示例的代码在KingbaseES和Oracle上均可运行。
2.1.3.1. 支持CREATE TABLE WITH OIDS语句
V8.6 支持create table with oids,表中的系统隐含列不再包含OID,但是这样创建的表,包含了一个用户隐含列oid,类型是oid。对于oracle rowid,需要用户创建隐含列rowid,类型是oid。
例:
create table tt (a int) with oids; ERROR: syntax error at or near "oids" create table tt1 (a int); select oid,relname from pg_class where relname = 'tt1'; oid | relname -------+--------- 16403 | tt1 (1 row)
2.1.3.2. select * from sequencename 语句
V8.3中select * from sequencename可以得到10列信息, V8.6 直接select * from sequencename只有3列,其余列可通过select * FROM all_sequences WHERE sequence_name=UPPER('sequencename')找到。
例:
V8.3:
CREATE SEQUENCE serial START 1;select * from serial; SEQUENCE_NAME | LAST_VALUE | START_VALUE | INCREMENT_BY | MAX_VALUE | MIN_VALUE | CACHE_VALUE | LOG_CNT | IS_CYCLED | IS_CALLED ---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+----------- SERIAL | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 0 | f | f (1 row)
V8.6 :
CREATE SEQUENCE serial START 1; select * from serial ; last_value | log_cnt | is_called ------------+---------+----------- 1 | 0 | f (1 row) select * FROM all_sequences WHERE sequence_name=UPPER('serial'); sequence_owner | sequence_name | min_value | max_value | increment_by | cycle_flag | order_flag | cache_size | last_number | start_value ----------------+---------------+-----------+---------------------+--------------+------------+------------+------------+-------------+------------- system | SERIAL | 1 | 9223372036854775807 | 1 | f | t | 1 | | 1
2.1.3.3. 函数 sys_guid()
V8.6 默认输出为name类型,如希望输出为bytea类型,需在配置文件中修改guid_default_return_type='bytea'并重启数据库,再通过以下命令实现:
select alter_sys_guid();
如希望输出为name类型,需在配置文件中修改guid_default_return_type='name'并重启数据库,再通过以下命令实现:
select alter_sys_guid();
2.1.3.4. 函数 get_byte(bit, int)
V8.6 不支持get_byte(bit,int)函数
V8.3:
test=# SELECT GET_BYTE(X'164da53ef', 4); GET_BYTE ---------- 239 (1 row)
V8.6 :
test=# SELECT GET_BYTE(X'164da53ef', 4) ; ERROR: function get_byte(bit, integer) does not exist LINE 1: SELECT GET_BYTE(X'164da53ef', 4) ; ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
2.1.3.5. 操作符
相比 V8.3, V8.6 完善了自定义操作符的处理逻辑。对于R3中所限制的自定义操作符中最后一个字符是‘+’或者‘-’的,如果前面包含‘~! @ ^ & ` %’这些字符中的任一字符,则不可以创建自定义操作符。比如在 V8.3中,创建自定义操作符‘~+’,将会报错,而 V8.6 中允许创建, V8.6 中禁用的自定义操作符有10个,包括:"!=+", "!=-", "^=+", "^=-", "||+", "||-", "^+", "^-", " |+", " |-"。这样也是为了尽可能保证处理逻辑与原型一致的基础上,还可以兼容Oracle的操作符。基于上面的处理逻辑,在 V8.3中,比如遇到"%-"这类操作符,实际上是会被当做两个(甚至多个)独立的操作符‘%’和‘-’,而 V8.6 中会认为这是用户自定义的操作符,会当做一个整体。所以在 V8.6 中如果想要将‘%-’操作符当做两个独立的操作符,需要修改应用,在操作符中间插入空格。这一点影响了应用兼容性。
对于大多数常用的 Oracle PL/SQL语句,KingbaseES均提供了支持。该措施使得Oracle应用程序移植到KingbaseES系统时,通常只需很少的代码变动。
下面给出KingbaseES中支持的Oracle PL/SQL语句。此外,若未做特殊说明,本节示例的代码在KingbaseES和Oracle上均可运行。
2.1.4.1. Internal关键字
区别:
V8.3函数创建带internal关键字;REVOKE EXECUTE ON INTERNAL FUNCTION
V8.6 函数创建不支持internal关键字;REVOKE语句中也不支持INTERNAL关键字
升级改写方案:
删除internal关键字
例2-1
V8.3:
CREATE OR REPLACE internal function pr1() return int AS $$ BEGIN return 1; END; $$language plsql; REVOKE EXECUTE ON INTERNAL FUNCTION
V8.6 :
CREATE OR REPLACE function pr1() return int AS $$ BEGIN return 1; END; $$language plsql; REVOKE EXECUTE ON FUNCTION
2.1.4.2. forall
区别:
V8.3支持forall语法及其功能
V8.6 不支持forall语法和功能
升级改写方案:
FORALL基本用法:
迭代器为lower..higher
迭代器为indices of collection [between lower and higher]
迭代器为values of index_collection
改写规则:
公有规则:
forall语句中有'save exception'的,忽略掉'save exception';
将'forall'改为'for';迭代器语句结束加上'loop'; dml语句结尾加上'end loop;';
三类的各自的规则:
1类:不做其他额外改动;
2类:
首先,
如果没有between..and
将迭代器变为 collection.first..collection.last;
否则将迭代器变为 lower..higher;
然后,将dml语句包裹在一个if语句中,条件是索引j有效;
3类:将迭代器变为 index_collection.first..index_collection.last;
将dml语句包括在一个if语句中,条件是keys(j)有效;
将dml语句内通过索引引用集合depts(j)改为depts(keys(j));
仍然存在的问题:
异常SQL%BULK_EXPCETIONS相关的,不支持
关联数组用于indices/values of 表现与oracle不一致
oracle的关联数组有exists方法,我们没有,改写失效
-------------------------------------------------------------------- --1 lower..higher DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22,44,66); BEGIN FORALL j IN depts.FIRST..depts.LAST DELETE FROM emp_temp WHERE department_id = depts(j); END; / --1 改写 DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22,44,66); BEGIN FOR j IN depts.FIRST..depts.LAST loop DELETE FROM emp_temp WHERE department_id = depts(j); end loop; END; / --2a indices of collection between .. and .. DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(11, 22, 44, 66); BEGIN FORALL j IN indices of depts between depts.first + 1 and depts.last DELETE FROM emp_temp WHERE department_id = depts(j); END; / --2a 改写 DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(11, 22, 44, 66); BEGIN FOR j IN depts.first+1..depts.last loop --dbms_output.put_line(j); if depts.exists(j) then DELETE FROM emp_temp WHERE department_id = depts(j); end if; end loop; END; / --2b indices of collection DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22, 44, 66); BEGIN FORALL j IN indices of depts DELETE FROM emp_temp WHERE department_id = depts(j); END; / --2b 改写 DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22, 44, 66); BEGIN FOR j IN depts.first..depts.last loop --dbms_output.put_line(j); if depts.exists(j) then DELETE FROM emp_temp WHERE department_id = depts(j); end if; end loop; END; / --3 values of DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22,44,66); TYPE NumListInt IS TABLE OF int; keys NumListInt := NumListInt(1,2,3); BEGIN FORALL j IN values of keys DELETE FROM emp_temp WHERE department_id = depts(j); END; / --3 改写 DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22,44,66); TYPE NumListInt IS TABLE OF int; keys NumListInt := NumListInt(1,2,3); BEGIN FOR j IN keys.first..keys.last loop --dbms_output.put_line(j); if keys.exists(j) then DELETE FROM emp_temp WHERE department_id = depts(keys(j)); end if; end loop; END; / ------------------------------------------------------------------ end ------------如果要测试,先执行以下 CREATE TABLE employees( employee_id NUMBER(6), first_name VARCHAR2(20), last_name VARCHAR2(25), department_id NUMBER(4), salary NUMBER(6) ); INSERT INTO employees VALUES (1,'zhang','san',11,10); INSERT INTO employees VALUES (2,'li','si',22,20); INSERT INTO employees VALUES (3,'liu','xiang',33,30); INSERT INTO employees VALUES (4,'sun','yang',44,40); INSERT INTO employees VALUES (5,'ye','shiwen',55,50); INSERT INTO employees VALUES (6,'chen','yibing',66,60); -- INSERT INTO emp_temp VALUES (2,'li','si',22,20); INSERT INTO emp_temp VALUES (4,'sun','yang',44,40); INSERT INTO emp_temp VALUES (6,'chen','yibing',66,60); SELECT * FROM employees; CREATE TABLE emp_temp AS SELECT * FROM employees ORDER BY employee_id, department_id; SELECT * from emp_temp; drop table emp_temp; drop table employees; ---------------------------------------------------------------- --存在的问题 --关联数组的情况, 不一致 --2 DECLARE TYPE NumList IS TABLE OF pls_integer index by pls_integer; depts NumList; BEGIN depts(1) := 1; depts(3) := 2; depts(5) := 3; FORALL j IN indices of depts between depts.first and depts.last DELETE FROM emp_temp WHERE department_id = depts(j); END; / --3 values of DECLARE TYPE NumList IS TABLE OF NUMBER; depts NumList := NumList(22,44,66); TYPE NumListInt IS TABLE OF pls_integer index by pls_integer; keys NumListInt; BEGIN keys(1) := 1; keys(3) := 2; keys(5) := 3; FORALL j IN values of keys DELETE FROM emp_temp WHERE department_id = depts(j); END; / ------------------ CREATE OR REPLACE PACKAGE BODY "CDS"."CDS_PKG_COMMON_FUNC" IS v_g_Debug BOOLEAN := FALSE; PROCEDURE CDS_P_DEBUG_SET(in_debug IN BOOLEAN) IS BEGIN v_g_Debug := in_debug; END CDS_P_DEBUG_SET; FUNCTION CDS_F_SPLIT_DATA (source_data IN VARCHAR2, delimiter_data IN VARCHAR2) RETURN cds_t_str_split IS j INT := 0; i INT := 1; source_data_len INT := 0; delimiter_data_len INT := 0; str VARCHAR2(4000); str_split cds_t_str_split := cds_t_str_split(); BEGIN source_data_len := LENGTH(source_data); delimiter_data_len := LENGTH(delimiter_data); WHILE j < source_data_len LOOP j := INSTR(source_data, delimiter_data, i); IF j = 0 THEN j := source_data_len; str := SUBSTR(source_data, i); str_split.EXTEND; str_split(str_split.COUNT) := trim(str); IF i >= source_data_len THEN EXIT; END IF; ELSE str := SUBSTR(source_data, i, j - i); if str is not null then str_split.EXTEND; str_split(str_split.COUNT) := trim(str); end if; i := j + delimiter_data_len; END IF; END LOOP; RETURN str_split; END; END CDS_PKG_COMMON_FUNC; --- declare TYPE t_student_var IS TABLE OF VARCHAR2(100); v_tbl_name t_student_var := t_student_var();--初始化 BEGIN raise notice 'v_tbl_name: %', v_tbl_name; v_tbl_name.extend;--扩展空间 select x into v_tbl_name(1) from test1 where id = 1; v_tbl_name.extend;--扩展空间 select x into v_tbl_name(2) from test1 where id = 2; v_tbl_name.extend;--扩展空间 select x into v_tbl_name(3) from test1 where id = 3; dbms_output.put_line('v_tbl_name(1): %'|| v_tbl_name(1)); dbms_output.put_line('v_tbl_name(2): %', v_tbl_name(2); dbms_output.put_line('v_tbl_name(3): %', v_tbl_name(3); raise notice 'v_tbl_name: %', v_tbl_name; end; CREATE OR REPLACE PACKAGE CDS_PKG_COMMON_FUNC AS FUNCTION CDS_F_SPLIT_DATA(source_data IN VARCHAR2, delimiter_data IN VARCHAR2) RETURN cds_t_str_split; END CDS_PKG_COMMON_FUNC; CREATE OR REPLACE PACKAGE BODY CDS_PKG_COMMON_FUNC IS v_g_Debug BOOLEAN := FALSE; PROCEDURE CDS_P_DEBUG_SET(in_debug IN BOOLEAN) IS BEGIN v_g_Debug := in_debug; END CDS_P_DEBUG_SET; FUNCTION CDS_F_SPLIT_DATA(source_data IN VARCHAR2, delimiter_data IN VARCHAR2) RETURN cds_t_str_split IS j INT := 0; i INT := 1; source_data_len INT := 0; delimiter_data_len INT := 0; str VARCHAR2(4000); str_split cds_t_str_split := cds_t_str_split(); BEGIN source_data_len := LENGTH(source_data); delimiter_data_len := LENGTH(delimiter_data); WHILE j < source_data_len LOOP j := INSTR(source_data, delimiter_data, i); IF j = 0 THEN j := source_data_len; str := SUBSTR(source_data, i); str_split.EXTEND; str_split(str_split.COUNT) := trim(str); IF i >= source_data_len THEN EXIT; END IF; ELSE str := SUBSTR(source_data, i, j - i); if str is not null then str_split.EXTEND; str_split(str_split.COUNT) := trim(str); end if; i := j + delimiter_data_len; END IF; END LOOP; RETURN str_split; END; END CDS_PKG_COMMON_FUNC;
2.1.4.3. oracle语法指定语言
区别:
V8.3创建oracle语法函数时能够指定LANGUAGE xxx语言
V8.6 创建oracle语法函数时不支持指定LANGUAGE xxx语言
升级改写方案:
删除LANGUAGE xxx语言子句
V8.3:
CREATE OR REPLACE function pr1 return int LANGUAGE plsql AS BEGIN return 1; END;
V8.6 :
CREATE OR REPLACE function pr1 return int AS BEGIN return 1; END;
2.1.4.4. 嵌套表定义CHAR类型省略长度
区别:
V8.3嵌套表定义CHAR类型省略长度,赋值超长, V8.3截断
V8.6 嵌套表定义CHAR类型省略长度,赋值超长,|version|报错
升级改写方案:
嵌套表定义CHAR类型省略长度,赋值正确
V8.3:
DO $$DECLARE TYPE type_name10 IS TABLE OF CHAR NOT NULL; nttypeelement10 type_name10:=type_name10('AAAA'); BEGIN RAISE NOTICE 'nttypeelement10(1)=%',nttypeelement10(1); EXCEPTION WHEN VALUE_ERROR THEN RAISE NOTICE 'VALUE_ERROR'; END$$;
V8.6 :
DO $$DECLARE TYPE type_name10 IS TABLE OF CHAR NOT NULL; nttypeelement10 type_name10:=type_name10('A'); BEGIN RAISE NOTICE 'nttypeelement10(1)=%',nttypeelement10(1); EXCEPTION WHEN VALUE_ERROR THEN RAISE NOTICE 'VALUE_ERROR'; END$$;
2.1.4.5. CREATE PACKAGE
区别:
V8.3CREATE PACKAGE 中文名的包 AS a int END;创建成功
V8.6 CREATE PACKAGE 中文名的包 AS a int END;创建失败
升级改写方案:
由于R6在包语法解析时更加严格,因此需要在a int后加’;’
V8.3:
CREATE PACKAGE 中文名的包 AS a int END;
V8.6 :
CREATE PACKAGE 中文名的包 AS a int; END;
V8.6 和 V8.3 版本新增以及变更能力明细如下表所示:
功能增强 |
实现完整性 |
|
---|---|---|
数据库对象类型 |
支持全局临时表 |
完整实现 |
Oracle directory |
不完整,不包括授权 |
|
支持Generated columns; |
完整实现 |
|
支持分区 |
不完整, 不支持分区的alter,不支 持全局索引,不支持 interval分区和reference 分区 |
|
兼容oracle 默认是大写存储的行为 |
不完 整,不支持oracle中大写 对象和小写对象同时存在 |
|
支持兼容oracle的 Force View |
完整实现 |
|
服务器编 码新增支持GBK、GB18030 |
完整实现 |
|
支持自动任务调度 |
完整实现 |
|
支持同义词 |
完整实现 |
|
内置数据库对象 |
支持XML函数 |
完整实现 |
支持postgis 2.5.2 和 3.0 |
支持linux |
|
支持oracle系统视图 |
完整实现 |
|
支持兼容Oracle 数据类型:Number、字符 类型、日期时间型、同时 支持相关的操作符、索引 、函数,支持类型转换。 |
完整实现 |
|
支持BLOB、CLOB、NCLOB等 大对象数据类型,同时支 持了相关的函数、接口。 |
完整实现 |
|
SQL操作 |
支持表达式coalesce |
完整实现 |
支持不指定group by情况下进行聚集操作 |
完整实现 |
|
支持Merge into |
完整实现 |
|
支持dml语句使 用return指定返回结果集 |
完整实现 |
|
支持子查询自动生成别名 |
完整实现 |
|
支持中文的逗号和空格 |
完整实现 |
|
新增约束的禁用启用 |
完整实现 |
|
支持在create table时指定列为not null |
完整实现 |
|
支持在create user时指定lock和unlock |
完整实现 |
|
支持在线重建index |
完整实现 |
|
支持内嵌WITH recursive 查询; |
完整实现 |
|
支持 SQL/JSON PATH特性; |
完整实现 |
V8.6 和 V8.3 客户端编程接口兼容性如下表所示:
接口类型 |
V8.3和V8.6的兼容性 |
---|---|
JDBC |
读写分离集群增加一个必填参数:nodelist,其它方面使用一致。 |
Activiti |
直接使用PG的配置方式,使用JDBC的PG形态驱动包。 |
Hibernate |
一致 |
OCI |
一致 |
Mybatis |
一致 |
ODBC |
一致 |
NET NDP |
一致 |
NET EF |
一致 |
PHP PDO |
一致 |
Perl PDI |
一致 |
Nodejs |
一致 |
Golang |
一致 |
Python |
一致 |
QT |
一致 |