6

有一个专栏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

更新:

似乎是一个错误。我找到了这个补丁,但仅适用于 SQL Server 的 ODBC 驱动程序 11(我尝试使用 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
4

2 回答 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 驱动程序。

于 2013-08-30T14:58:47.037 回答
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

于 2013-06-05T17:06:33.580 回答