使用 PHP oci_pdo 和 ORACLE db 进行日期 - TO_DATE 不起作用

问题描述 投票:0回答:2

我正在尝试使用 php 和 pdo_oci 在 Oracle 数据库日期列中写入日期,但出现上述错误,并且无法继续:

SQLSTATE[HY000]:一般错误:1858 OCIStmtExecute:ORA-01858:在需要数字的位置找到非数字字符 (ext\pdo_oci\oci_statement.c:155)

代码:

$invoiceUpdate->PAYMENT_DATE = "TO_DATE('06/MAR/24','dd/mon/yy HH24:MI:SS')";

将日期和时间写入 Oracle 数据库日期类型列

php oracle date
2个回答
0
投票

你在评论中说你的实际SQL是:

UPDATE TABLE SET PAYMENT_DATE = :PAYMENT_DATE 

绑定变量定义为:

'PAYMENT_DATE' => string 'TO_DATE('06/Mar/24 16:17:12','dd/mon/yyyy HH24:MI:SS')' (length=54)

这是绑定一个string而不是日期。它有效地为您提供:

UPDATE TABLE SET PAYMENT_DATE = 'TO_DATE(''06/Mar/24 16:17:12'',''dd/mon/yyyy HH24:MI:SS'')'

因为它是一个字符串,Oracle不会评估TO_DATE函数。它不是一个函数,它只是一个 54 字节长的字符串。因为您要为此设置一个日期字段,Oracle 将尝试使用您的数据库(或会话)

NLS_DATE_FORMAT
进行隐式日期转换,这肯定不知道如何处理
T, O, _, D, A, T, E,
等字母。因此会出现错误。

要修复此问题,请绑定实际的日期值,而不是字符串。每个客户都有一些方法可以做到这一点,因此请查阅您的语言文档。您可以通过连接到 SQL 而不是通过绑定变量来使其工作,因为 Oracle 会将 TO_DATE 评估为函数,但您会创建不可共享的游标并在解析上花费额外的时间。使用绑定变量要好得多,但是您需要将

date
(但这在您的客户端环境中看起来)绑定到日期槽,而不是字符串。


0
投票
使用 var - $date = date('d/M/y H:i:s') 获取实际日期,然后我使用 $date var 的值 PAYMENT_DATE - "TO_DATE('{$date}','日/月/年 HH24:MI:SS')";完整的语句是: UPDATE TABLE SET PAYMENT_DATE = :PAYMENT_DATE 'PAYMENT_DATE' => string 'TO_DATE('06/Mar/24 16:17:12','dd/mon/yyyy HH24:MI:SS')' (长度=54)

您绑定了一个字符串值;该字符串的内容不会被解释为函数调用,它将尝试使用文字字符串值。当您将其分配给日期列时,它会隐式尝试将其转换为正确的数据类型,所以您实际上最终要做的是:

UPDATE TABLE SET PAYMENT_DATE = to_date(:PAYMENT_DATE)

使用您的 NLS 设置,FWIW;如果你用字符串替换绑定,看起来像;

UPDATE TABLE SET PAYMENT_DATE = to_date(q'^TO_DATE('06/Mar/24 16:17:12','dd/mon/yyyy HH24:MI:SS')^')

这确实会抛出 ORA-01858,因为使用像 DD-MON-RR 这样的正常 NLS 设置,它会期望该字符串以两位数字开头,而不是 
TO

。 (根据 NLS 设置,它可能会抛出不同的错误...)

可以

TO_DATE()调用移至固定查询中:

UPDATE TABLE SET PAYMENT_DATE = TO_DATE(:PAYMENT_DATE, 'DD/MON/YYYY HH24:MI:SS', 'NLS_DATE_LANGUAGE=ENGLISH')

然后绑定字符串值:

$invoiceUpdate->PAYMENT_DATE = "06/MAR/24 16:17:12";

但如果可以的话,最好绑定一个实际的数据值,避免双向转换。

© www.soinside.com 2019 - 2024. All rights reserved.