You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 6+Doctrine操作Oracle Date字段遇ORA-01861错误求助

解决Symfony 6 + Doctrine + Oracle中日期字段更新的ORA-01861错误

核心原因

ORA-01861错误源于Doctrine传递的日期格式与Oracle会话默认格式不匹配。Oracle默认NLS_DATE_FORMAT通常为DD-MON-RR(如08-JUN-20),而Doctrine默认以YYYY-MM-DD HH:MI:SS格式传递日期参数,二者格式冲突导致报错。

解决方案

1. 配置Oracle会话日期格式

在Doctrine数据库连接配置中添加会话级日期格式设置,强制Oracle使用Doctrine兼容的格式。修改config/packages/doctrine.yaml:

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver: oci8 # 或pdo_oci,根据实际驱动选择
                host: '%env(ORACLE_HOST)%'
                port: '%env(ORACLE_PORT)%'
                dbname: '%env(ORACLE_SID)%'
                user: '%env(ORACLE_USER)%'
                password: '%env(ORACLE_PASSWORD)%'
                options:
                    driverOptions:
                        # 初始化会话时设置日期格式
                        1002: "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
                        # 可选:若有TIMESTAMP类型字段,同步设置时间戳格式
                        1003: "ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"

其中1002和1003是OCI驱动的初始化命令常量,用于连接建立时执行SQL配置会话。

2. 确认实体字段类型匹配

Oracle的DATE类型实际存储年、月、日、时、分、秒,Doctrine中使用Types::DATETIME_MUTABLE或Types::DATETIME_IMMUTABLE是正确的。若业务仅需日期部分,可改用Types::DATE,修改实体字段定义:

#[ORM\Column(type: Types::DATE, nullable: true)]
private ?\DateTimeInterface $next_expected_date = null;

3. 确保日期对象时区一致性

DateTime对象的时区差异可能导致格式化异常,建议创建日期时明确指定时区:

// 带时区创建日期对象
$next_expected_date = \DateTimeImmutable::createFromFormat(
    'Y-m-d', 
    "2021-01-04",
    new \DateTimeZone('UTC')
);

// 或转换已有DateTime对象为Immutable并指定时区
$date = new \DateTime("2021-01-04 23:59:59", new \DateTimeZone('UTC'));
$next_expected_date = \DateTimeImmutable::createFromInterface($date);

4. 原生查询验证(备选)

若上述方案无效,可通过Doctrine原生查询确认问题根源:

$entityManager = $this->getDoctrine()->getManager();
$conn = $entityManager->getConnection();

$sql = "UPDATE your_table SET next_expected_date = TO_DATE(:date, 'YYYY-MM-DD HH24:MI:SS') WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([
    'date' => '2021-01-04 23:59:59',
    'id' => $yourEntityId
]);

若原生查询成功,说明问题出在实体映射或连接配置,回到方案1和2排查。

内容的提问来源于stack exchange,提问作者phpbutcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:43:16