为什么 oci_bind_by_name 在 oracle 函数中不起作用

why oci_bind_by_name not working if inside oracle function

抱歉我的英语不好。我想如果我把我的代码放在这里会更容易。所以这是我尝试过的:

//这是有效的

$sql = "select ID, NAME, BDATE from EMPLOYEES where BDATE >= DATE '2020-01-01'"; 

//但是当我尝试这样做时,它失败了:

$sql = "select ID, NAME, BDATE from EMPLOYEES where BDATE >= DATE :bdate"; //this is 
$compiled = oci_parse($conn, $sql);
oci_bind_by_name($compiled, ":bdate", "2020-01-01");

以上将引发此错误:

"code":936,"message":"ORA-00936: missing expression"

我尝试过其他类似的方法:

//失败

$sql = "select ID, NAME, BDATE from EMPLOYEES where BDATE >= TO_DATE(:bdate, 'YYYY-MM-DD')"; 
oci_bind_by_name($conn, ':bdate', '2020-01-01');

以上将引发此错误:

"code":1847,"message":"ORA-01847: day of month must be between 1 and last day of month"

//当我放入 DATE、TO_DATE、UPPER 等函数时总是失败

$sql = "select ID, NAME, BDATE, STATUS from EMPLOYEES where upper(STATUS) = upper(:status)"; 

//In子句中的事件也会失败

$sql = "select ID, NAME, BDATE, STATUS from EMPLOYEES where upper(STATUS) in (:status1, :status2)"; 
oci_bind_by_name($compiled, ":status1", "SINGLE");
oci_bind_by_name($compiled, ":status2", "MARRIED");

谁能告诉我如何解决这个问题? 我遵循了文档中的许多教程,以及另一个 Whosebug 的答案。但是没有任何效果。

或者是不是我错过了在我的网络服务器上设置的东西?或者在我的数据库服务器上?

仅供参考,我正在使用 PHP7.2、OCI8、Oracle 11g。

非常感谢。

这应该有效:

where BDATE >= TO_DATE(:bdate, 'YYYY-MM-DD')

但前提是您提供的日期值与您指定的格式完全相同:YYYY-MM-DD。你得到的错误:

ORA-01847: day of month must be between 1 and last day of month

表示您提供了无效的字符串,例如2020-05-38 - 任何一个月都没有 38 天,Oracle 预计数字在 1 到 31 之间(因为 5 月有 31 天)。


使用

检查默认日期格式
SQL> select * From nls_session_parameters where parameter = 'NLS_DATE_FORMAT';

PARAMETER            VALUE
-------------------- --------------------
NLS_DATE_FORMAT      DD.MM.RR

SQL>

这意味着您 - 在我的数据库中 - 将今天日期的值作为 18.05.20 传递。

这对我在 php 7.4,Oci8/Oracle 19c 数据库上有用。(我从未在 php 上工作过,只是在这里和那里搜索)

    $sql = "SELECT ename FROM emp WHERE hiredate > TO_DATE(:hdate,'YYYY-MM-DD')";
    $stid = oci_parse($conn, $sql);
    $hdate = "1980-01-01";
     oci_bind_by_name($stid,':hdate', $hdate);
   // oci_bind_by_name($stid,":hdate", $hdate);  //this line also works i.e double quotes

编辑:- IN 子句也适用于 me.This 是我了解到你不能在 OCI_BIND 中传递文字值,我首先将文字分配给变量

$sql = "SELECT ename FROM emp WHERE job IN (:job1,:job2)";
$stid = oci_parse($conn, $sql);
$job1 ='CLERK';
$job2 = 'SALESMAN';
oci_bind_by_name($stid,':job1', $job1);
oci_bind_by_name($stid,':job2',$job2);
oci_execute($stid);

检查这些 link1 link2 以获取适用于 Oracle 数据库的示例

DATE '2020-01-01' 是 ANSI date literal 语法。这是一种在代码中键入原始日期的机制,它对变量或占位符没有意义,因此会出现错误。

如前所述,您可以使用 TO_DATE() function 作为替代。