当前位置:网站首页>金仓数据库 KingbaseES V8.3至V8.6迁移最佳实践(2. KingbaseES V8.3和 V8.6 兼容性)
金仓数据库 KingbaseES V8.3至V8.6迁移最佳实践(2. KingbaseES V8.3和 V8.6 兼容性)
2022-07-28 21:46:00 【沉舟侧畔千帆过_】
2. KingbaseES V8.3和 V8.6 兼容性
本部分包含如下章节:
KingbaseES V8.3 和 V8.6 兼容特性概览
2.1. KingbaseES V8.3 和 V8.6 兼容特性概览
本章节包含以下内容:
2.1.1. 兼容性开关
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. 模式和对象
本节内容旨在为移植过程的相关模式修改操作提供参考指南。
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
2.1.3. SQL语句
对于大多数常用的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 中如果想要将‘%-’操作符当做两个独立的操作符,需要修改应用,在操作符中间插入空格。这一点影响了应用兼容性。
2.1.4. PL/SQL语言
对于大多数常用的 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;
2.1.5. 版本新增能力和变更能力明细
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特性; | 完整实现 |
2.1.6. 支持的客户端编程接口兼容性
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 | 一致 |
边栏推荐
- 字节8年女测试总监工作感悟—写给想转行或即将进入测试行业的女生们...
- With the "integration of driving and parking", freytek's high-performance domain controller leads the new track
- Function function
- 智能电视与小程序的结合
- After reading MySQL database advanced practice (SQL xiaoxuzhu)
- 行泊一体迎爆发期,抢量产还是修技术护城河?
- Hands on Teaching of servlet use (1)
- trivy【3】自定义扫描策略
- 如何开一家盈利的健身房?我用1年回本的经验告诉你,别谈恋爱
- Text is hidden beyond and ellipsis is displayed
猜你喜欢

How to open a profitable gym? I tell you from one year's experience that don't fall in love

Retrofit Usage Summary

集火全屋智能“后装市场”,真正玩得转的没几个

Huawei wireless device configuration uses WDS technology to deploy WLAN services

Thesis reading (3) - googlenet of classification

22牛客多校day1 I - Chiitoitsu 概论dp

Media query adaptation

Runloop principle (I)

Rouyi cloud platform - how to realize the launch and login functions of the project and how to create new modules

MySQL数据库的基本概念以及MySQL8.0版本的部署(一)
随机推荐
Kotlin function nesting
字节8年女测试总监工作感悟—写给想转行或即将进入测试行业的女生们...
[filter tracking] target tracking based on EKF, TDOA and frequency difference positioning with matlab code
当初的“你“为什么做测试/开发程序员?自己存在的价值......
Rhce第二天
Achieve high throughput through Wi Fi 7 - insight into the next generation of Wi Fi physical layer
Terminal output G_ Debug() information
RouYi-Cloud平台 ---项目的启动、登录功能是怎么实现的、怎么样创建新模块
How strong is this glue?
Rouyi cloud platform - how to realize the launch and login functions of the project and how to create new modules
String string
[physical application] atmospheric absorption loss with matlab code
【数据挖掘工程师-笔试】2022年大华股份
6 个超级良心的开源教程!
There are four ways for Nacos to configure hot updates and multiple ways to read project configuration files, @value, @refreshscope, @nacosconfigurationproperties
Price for volume has encountered "six consecutive declines" in sales. Can Volvo, which is no longer safe, turn around?
c语言进阶篇:指针(二)
Typescript类的使用
Solve the exception that all control files are damaged
General paging - background