pdo-odbc 不适用于绑定值,nvarchar 和 text 在等于运算符中不兼容
Posted
技术标签:
【中文标题】pdo-odbc 不适用于绑定值,nvarchar 和 text 在等于运算符中不兼容【英文标题】:pdo-odbc doesn't work whit bind values, nvarchar and text are incompatible in the equal to operator 【发布时间】:2013-05-08 02:45:47 【问题描述】:有一个专栏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 Driver 11;现在正在工作。
php 5.4.15 unixODBC 2.3.0 适用于 SQL Server 的 ODBC 驱动程序 11 sql-server-2012 centos-x64 6.4【问题讨论】:
嗯,似乎是一个错误。现在我正在尝试用我找到的补丁编译 PHP。 在 FreeTDS 中,只需在freetds.conf
中设置 tds version = 7.2
即可!
【参考方案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 驱动程序。
【讨论】:
供参考:Ubuntu 14.04 php 5.5.9 仍然存在问题。我收到“强制转换规范的字符值无效”。讨论于connect.microsoft.com/SQLServer/feedback/details/737751/… 刚刚发现使用 odbc_connect,odbc_prepare 适用于 MSSQL Driver 11 中的查询和存储过程【参考方案2】:同样的错误:
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、ODBC 11 for SQL Server
【讨论】:
以上是关于pdo-odbc 不适用于绑定值,nvarchar 和 text 在等于运算符中不兼容的主要内容,如果未能解决你的问题,请参考以下文章