国产数据库信创:多数据库对比

Posted by Futari on 2024-05-12
Estimated Reading Time 5 Minutes
Words 1.5k In Total
Viewed Times

脚本

TDSQL:

腾讯MySQL内核,语法通用

MySQL:
1
2
3
4
5
6
7
8
9
10
DELIMITER $$
DROP FUNCTION IF EXISTS NVL;
CREATE FUNCTION NVL (expression VARCHAR(255), replacement VARCHAR(255))
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
RETURN IFNULL(expression, replacement);
END $$

DELIMITER ;
达梦:

Oracle内核,DMDriver驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
declare
num NUMBER;
begin

select count(1)
into num
from user_tab_columns
where table_name = 'CHART'
and column_name = 'VALUE_DIRECTION';
if
num=0 THEN
execute immediate 'alter TABLE CHART add VALUE_DIRECTION VARCHAR2(10)';
end if;
end;
/可有可无
Oracle:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
declare
num NUMBER;
begin

select count(1)
into num
from user_tab_columns
where table_name = 'CHART'
and column_name = 'VALUE_DIRECTION';
if
num=0 THEN
execute immediate 'alter TABLE CHART add VALUE_DIRECTION VARCHAR2(10)';
end if;
end;
/必须要有

execute immediate在Oracle和Dm都可以省略

最后还有一个LightDB,使用的是PostgreSQL的内核,启动也是PostgreSQLDriver,语法和Oracle基本相同

:::success
但是PostGre是和Oralce兼容最好也就是特性最接近的数据库,所以基础语法、脚本语言都与Oralce基本相同,区别在Oracle有的包在Postgre中没有,相当于Oracle是扩展版的PostGreSQL

PostgreSQL需要极致贴近Oracle特性的话,需要扩展包orafce,对oracle很多特性进行不同途径实现,减少工程不适配代码的迁移量。

:::

See平台的为数据库对应的命令行执行工具,比如dm对应的是diSQL,Oracle使用的是SqlPlus-client工具,语法上虽然大致想相同,但是由于方式不同,所以产生了分隔符等问题,如果只是在Client客户端执行是不会出现这个问题的。

:::success
非常重要的一点:

工具会对执行语句进行处理,不同工具也就是不同客户端,不同客户端连接同种数据库,对同样的SQL解释也不同,比如SQLPLUS就会对&等符号进行解义,保持原意义必须进行转义,navicat中也没有user_tab_colnums内指表,但sqlplus等客户端就可以查到

:::

备注:

与Java

在编码规范上,为什么实体类的类型要和数据库规范上的映射类型相对应?

我们知道,数据库设置为char,String是可以完成映射的,但是要区分不同的数据库

对于Mysql,插入的字符串即为最终字符串,而Oralce的字符串会右补齐到char的位数

所以对于以下情况:

Oracle:实体类使用String,数据库使用Char(10),那么存入xyz,会被补全为xyz

PS

不管是使用数据库工具比如navicat手动插入还是使用mp的insert或者xml插入(JDBC连接),Oracle都会进行补全原因是String并不会做任何操作,而0ralce的特性决定了插入Char一定会发生补全现象

也正因为String对于Java和数据库的get/select都不会做补全处理,所以经过数据库补全的数据是get不到的,因为有空格所以需要使用控制变量法

让对加入和获取字段操作的处理都让Java处理或者都让数据库处理,所以实体类使用MgChar,数据库使用Char就相当于把查和改的补空格操作都交给了Java,正好完全适配了,不管什么数据库

所以实体类使用MaChar都会补齐空格,所以我们分以下四种情况

左边为Java类型,右为数据库字段类型(注意下面不关注Char的插入超长问题)

String-Char

仅Oracle会出现数据不对应问题问题,因为其他的数据库插入xyz时,不会自动转换为xyz ,注意这里的插入指的是不管是代码还是手动SQL语句插入的方式,都是一样的

String-varchar/varchar2

这种情况都可以适配,但是注意在Oracle环境下,如果新建的字段和原字段存在表关联,那么新建字段就不能为VARCHAR/varchar2了,原因是原来的数据是补空格的,关联varchar肯定关联不到数据

MgChar-varchar/varchar2

假如传入数据为new Mgchar4(“xy”),那么插入数据库为xy ,那就和我们上面说的一样了,都交给Mgchar处理

MgChar-Char**

完全对应,无问题

:::success
如果使用的是pg或者mysql内核,那么不管怎么选类型都是是不会出现任何问题的,因为插入时只要不超过长度,插多少就是多少,数据库的char不会做控制,所以一定没有数据不对应的问题

:::

那么如果有个数据是Mgchar-char维护的,我现在使用String-Char多个路径维护的情况呢?

难道Mysql等库不会出现问题吗?

这种情况数据是没有补空格的,我们使用mp也是可以查到的,使用数据库工具也可以查到,原因是mysql在插入char数据的时候,就相当于将数据库数据进行了trim(但是这仅仅适用于非Oralce环境,一旦环境含有了Oracle,那么此种维护方式肯定不可取了)

重要点:Oracle-**JDBC在查询时,不会对Char进行处理,JDBC的插入操作却会进行补全**

SQL-Char-Varchar字段连接

我们知道,对于Oracle,输入’a’,数据库里如果为char(2),用Java代码查,是查不到的

那么如果在表关联的时候,长度不同的Char进行关联,能查到吗

答案是可以关联上

:::info
原因是数据的变量等(字面值)经过的是JDBC的处理,所以和Oracle驱动必须完全对应

但是对于SQL语句非字面值或填充变量部分,JDBC是不会处理的,所以能不能关联上完全取决于Oralce执行器,所以就像Oracle-where可以自动处理空格一样,同类型char也可以直接忽略进行关联

但是不同类型,char-varchar无法对应!

:::

这篇文章总结很好:

ORACLE中关于 char 和 varchar2 的比较 - 黄景新 - 博客园 (cnblogs.com)

但是这是Oracle默认执行器,字面量部分的结论用JDBC应该正好是相反的


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !