Symfony+Doctrine操作Oracle日期报错ORA-01861,求替代方案
解决Symfony+Doctrine操作Oracle时ORA-01861日期格式不匹配问题
ORA-01861本质是输入日期字符串与Oracle会话期望的格式不匹配,你的数据库默认格式是DD-MON-RR,而Doctrine默认使用的日期格式与其不一致,废弃的OracleSessionInit本质是通过修改会话格式解决问题,以下是合规替代方案:
方案1:自定义Doctrine postConnect事件监听器
自己实现一个监听器,在数据库连接建立后执行会话格式配置,完全替代废弃的OracleSessionInit:
- 创建监听器类:
// src/Doctrine/EventListener/OracleSessionConfigListener.php namespace App\Doctrine\EventListener; use Doctrine\DBAL\Event\ConnectionEventArgs; class OracleSessionConfigListener { public function postConnect(ConnectionEventArgs $args): void { $connection = $args->getConnection(); // 配置会话日期格式为Doctrine兼容的格式,也可改为你的数据库默认格式'DD-MON-RR' $connection->executeStatement("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'"); // 若需处理时间戳,补充配置 $connection->executeStatement("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"); } }
- 在
services.yaml中注册监听器:
services: App\Doctrine\EventListener\OracleSessionConfigListener: tags: - { name: doctrine.event_listener, event: postConnect }
方案2:直接在DBAL连接配置中添加初始化SQL
无需编写监听器,直接在Doctrine连接配置中指定连接初始化时执行的SQL语句:
修改config/packages/doctrine.yaml:
doctrine: dbal: connections: default: driver: oci8 # 其他连接参数(host、port、dbname等)保持不变 options: # 一次性设置日期和时间戳格式 initSql: "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD', NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
关键说明
- 两种方案核心都是让Oracle会话的日期格式与Doctrine传输的格式一致,你可以根据需求选择将会话格式设为Doctrine默认的
YYYY-MM-DD,或者改为数据库默认的DD-MON-RR(只需修改SQL中的格式字符串)。 - 实体字段类型保持
date/datetime即可,无需额外调整,Doctrine会自动完成DateTime/Date对象与字符串的转换。
内容的提问来源于stack exchange,提问作者user16198769
相关产品推荐
相关产品推荐

