将日期参数绑定到预准备语句时出错 -- 将 PHP PDO/ODBC 与 SQL Server 配合使用


Error when binding date parameter to prepared statement -- Using PHP PDO/ODBC with SQL Server

我与连接到 SQL Server (v8.00.2039 SP4 Standard Edition) 数据库的 ODBC (v2000.86.359.00) 有一个 pdo 连接。

这有效:

$id = 486;
$duedate = 'June 27, 2012';
$query ="INSERT into AssetHistory (AssetID, DateDue) Values($id, $duedate);";                   
$noParams = $db->exec($query);
$db->query($query);

但是,如果我尝试使用这样的预准备语句:

$sql = 'INSERT into AssetHistory 
    (AssetID, DateDue)
    Values(:id, :duedate);';                
$input = array(':id'=>486, ':duedate'=>'June 27, 2012');
$smt = $db->prepare($sql);
$smt->execute($input);

我收到此错误(来自$smt->错误信息()):

 "[Microsoft][ODBC Driver Manager] Function sequence error (SQLExecute[0] at ext'pdo_odbc'odbc_stmt.c:254)"

我试过:1) 将:d日期括在单引号中2) 将日期绑定到 unix 时间戳整数3) 绑定:d uedate 到 php DateTime 对象4) 在准备之前只在 sql 语句中插入$duedate

在这一点上,我可能会坚持使用 $db->query 方法并尽我所能清理输入,但我真的很感激任何建议。

在 Windows Server 2003 机器上使用 PHP 5.38。

更新:我已经从这个问题的先前版本中删除了一些变量。错误消息已更改,但最终结果相同。

我还尝试手动绑定参数,如下所示:

$smt->bindValue(':id', 486, PDO::PARAM_INT);
$smt->bindValue(':duedate', 'June 27, 2012', PDO::PARAM_STR);

除了像这样将转换函数添加到 sql 之外:

$sql = 'INSERT into AssetHistory 
   (AssetID, DateDue)
Values(:id, convert(datetime,:duedate, 100));';

其中返回: "计数字段不正确或语法错误"

而且我注意到SQL Server在Unix时间戳方面并不好玩...

最后通过下载并安装sqlsrv php驱动程序(我使用的是2.0版)和SQL Server 2008本机客户端来解决此问题。

只需对 $dsn 参数稍作调整,其余代码就像魔术一样工作——无需绑定、转换或强制转换。

我最终只使用了php_pdo_sqlsrv_53_ts_vc9.dll,但请确保您选择了正确的线程安全/非线程安全版本的驱动程序,因为 php.ini 中的错误 dll 会使您的服务器崩溃。

你试过时间吗?

 $phpdate = strtotime( $duedate);

您也可以尝试在语句中使用SQL的CONVERT

 convert(datetime, :duedate, 100)

SQL中的数据类型是日期时间,对吗?

或尝试:

array(':id'=>486, ':borrower'=> 'name', ':loaner'=>'KOPERW', ':duedate'=>strtotime($duedate),
array(':id'=>486, ':borrower'=> 'name', ':loaner'=>'KOPERW', ':duedate"=>$duedate),"0000-00-00 00:00:00"
如果

设置了参数化查询,但随后未能在参数列表中传递所需数量的参数,则可能会出现"COUNT 字段不正确或语法错误"。

但是,您的代码在这方面看起来不错。