【问题标题】:Error when binding date parameter to prepared statement -- Using PHP PDO/ODBC with SQL Server将日期参数绑定到准备好的语句时出错 - 将 PHP PDO/ODBC 与 SQL Server 结合使用
【发布时间】:2012-06-26 18:34:14
【问题描述】:

我有一个使用 ODBC (v2000.86.359.00) 连接到 SQL Server (v8.00.2039 SP4 标准版) 数据库的 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->errorInfo()):

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

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

此时我可能无法使用 $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));';

返回: "COUNT 字段不正确或语法错误"

而且我注意到 SQL Server 并没有真正 play nice 带有 unix 时间戳...

【问题讨论】:

  • 带有格式化日期的字符串 -- 我试过 'June 27, 2012' 和 '2012-06-27 00:00.000'
  • 好吧,你试过长格式:$smt->bindValue(':duedate',$duedate,PDO::PARAM_INT);?或者,投射$duedate=intval($duedate);
  • 感谢您的所有建议,我已更新问题。在这一点上,我已经尝试了所有建议但没有成功。

标签: php sql-server odbc


【解决方案1】:

最后通过下载并安装sqlsrv php drivers(我使用的是2.0版)和SQL Server 2008 Native Client解决了这个问题。

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

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

【讨论】:

    【解决方案2】:

    你试过strtotime吗?

     $phpdate = strtotime( $duedate);
    

    您也可以尝试在声明中使用SQL's CONVERT

     convert(datetime, :duedate, 100)
    

    SQL 中的数据类型是 datetime,对吗?

    或者试试:

    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"
    

    【讨论】:

    • 此时我在数组中使用字符串文字:$input = array(':id'=>486, ':borrower'=> 'JOHNSMITH', ':loaner'=>'KOPERW',':duedate'=>'June 27, 2012', ':loaneragain'=>'KOPERW' );
    • 在此之前我尝试了$duedate = strtotime('June 27, 2012');,它返回了一个整数和同样的错误。
    • 是的,SQL 中的数据类型是 datetime。
    【解决方案3】:

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

    不过,您的代码在这方面看起来还不错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 2017-03-13
      • 2010-10-14
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      相关资源
      最近更新 更多