Oracle数据库不用to_date函数来插入日期date类型字段数据

公司有一个客户是用Oracle数据库的,我们开发的软件是用druid + mybatis来连接数据库的;平时开发环境是用mysql来测试,客户也多数是用mysql, 直接执行下面的insert语句是正常的,在SQL Server下面执行也正常;但在Oracle下面执行却会报 “java.sql.SQLDataException: ORA-01861: 文字与格式字符串不匹配” 的错误。

insert into AAA(BBB) VALUES('2022-01-06 16:15:21');

有点郁闷,觉得Oracle不兼容标准SQL,这么难用还收费为什么还有人用呢?客户DBA还在嘲笑我老老实实用to_date函数来改代码吧。因为是动态的SQL,又要兼容多种数据库,所以我不想修改代码。于是继续网上搜索不用to_date函数来插入,找到了一些线索,通过修改NLS_DATE_FORMAT 变量来执行:
直接在navicat或sql plus等工具中执行:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
insert into AAA(BBB) VALUES('2022-01-06 16:15:21');

然后在执行上面的insert语句居然成功了。但这只是会话级别的,要想永久生效需要执行下面的语句,并重启数据库:

ALTER SYSTEM SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' SCOPE=SPFILE;

可以通过下面这个命令查看是否生效:

SELECT * FROM v$nls_parameters;

虽然在navicat中可以了,但在java程序中还是会报同样的错误,继续按网上的文章配置环境变量:

SET NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK
SET NLS_LANG = "Simplified Chinese_china".ZHS16GBK

各种组合都试过了,也还是不行。我觉得也可能我们Jdbc驱动程序版本过低,但是我们驱动程序有修改过,不能升级,所以也没有去升级测试;

试过在java代码中先执行ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';再执行insert语句也是生效的,于是想用druid的connectionInitSqls配置项在数据库连接初始化的时候执行,但配置了也不生效,大看了一下druid的源码,没看到connectionInitSqls属性调用的地方,可能connectionInitSqls并没有实现。

最后的办法只能通过触发器来改变这个值了,就是在登录后自动在会话中修改这个值:

CREATE OR REPLACE TRIGGER LOGINTRG
AFTER LOGON ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DD HH24:MI:SS''';
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_TIMESTAMP_FORMAT=''YYYY-MM-DD HH24:MI:SS''';
END LOGINTRG;

我没有执行权限,客户那边的DBA还不想帮了执行,在我的坚持下他还是帮我执行了。结果是可以的,这样就不用修改我们java代码了。

如果有TIMESTAMP类型字段,也可以用类似的办法来配置一下:

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SYSTEM SET NLS_TIMESTAMP_FORMAT= 'YYYY-MM-DD HH24:MI:SS' SCOPE=SPFILE;

你可能感兴趣的:(Oracle数据库不用to_date函数来插入日期date类型字段数据)