pdo-odbc不能使用绑定值,nvarchar和text在等于运算符中不兼容

时间:2013-05-13 23:17:44

标签: php sql-server pdo odbc freetds

有一列url(nvarchar(200), not null)

<?php
//
$pdo = new PDO('odbc:mssql', 'xxx', 'yyy');
$pdo->setAttribute(PDO::ATTR_PERSISTENT, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

// plain sql query: WORKS FINE!
$sth = $pdo->prepare("SELECT COUNT(*) FROM pagina WHERE url = '/webito'");
$sth->execute();

// using bindValue: ERROR!
$sth = $pdo->prepare("SELECT COUNT(*) FROM pagina WHERE url = :unique_value");
$sth->execute(array('unique_value' => '/webito'));

返回错误:

Warning: PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 402 [FreeTDS][SQL Server]The data types nvarchar and text are incompatible in the equal to operator. (SQLExecute[402] at /builddir/build/BUILD/php-5.4.15/ext/pdo_odbc/odbc_stmt.c:254) in /root/php/test.php on line 13

这是一个错误吗?

使用:php 5.4.15,unixodbc 2.2.14,freetds 0.91,sql-server-2012,centos-x64 6.4

更新

似乎是bug。我找到了这个patch,但仅适用于ODBC Driver 11 for SQL Server(我尝试使用FreeTDS,没有运气)。我设法从源代码安装PHP,应用此补丁并从FreeTDS更改为SQL Server的ODBC驱动程序11;现在正在努力。

  • php 5.4.15
  • unixODBC 2.3.0
  • 用于SQL Server的ODBC驱动程序11
  • SQL服务器-2012
  • centos-x64 6.4

2 个答案:

答案 0 :(得分:1)

对此进行了相当多的研究后,似乎pdo_odbc在64位架构上存在问题:它采用32位SQLLEN和SQLULEN大小构建。微软的驱动程序曾经是以这种方式构建的,这可能就是PHP效仿的原因。 MS已经开始正确地遵循ODBC规范,但显然PHP没有。

问题中引用的补丁修复了PHP源代码中的一个问题,但似乎并非所有此类问题。使用MS驱动程序和修补过的PHP,我仍然无法运行准备好的语句。

我实际上在使用Easysoft的驱动程序时发现了同样的问题,并且与他们讨论问题后发现pdo_odbc是罪魁祸首。他们能够为我提供一个使用32位大小构建的64位驱动程序,并且工作正常。

在64位PHP被修补以使用64位SQLLEN和SQLULEN大小之前,看起来最好的免费解决方案是使用32位PHP和ODBC驱动程序。

答案 1 :(得分:0)

同样的错误:

PDOStatement::execute(): SQLSTATE[22001]: String data, right truncated: 0 [Microsoft][SQL Server Native Client 11.0]Die Zeichenfolgedaten wurden rechts abgeschnitten (SQLExecute[0] at ext\pdo_odbc\odbc_stmt.c:254)

Win7 64位,PHP 5.4.12,SQL Server Express 2012,SQL Server的ODBC 11