pdo-odbc не работает со значениями привязки, nvarchar и текст несовместимы в операторе равенства

Есть столбец 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.

Обновление:

Похоже, это ошибка. Я нашел этот патч, но работает только с Драйвер ODBC 11 для SQL Server (я пробовал с FreeTDS, но безуспешно). Мне удалось установить PHP из исходного кода с применением этого исправления и перейти с FreeTDS на ODBC Driver 11 для SQL Server; сейчас работает.

  • PHP 5.4.15
  • UnixODBC 2.3.0
  • Драйвер ODBC 11 для SQL Server
  • SQL-сервер-2012
  • центрос-x64 6.4

person Luistar15    schedule 13.05.2013    source источник
comment
Ну видимо баг. Сейчас пытаюсь скомпилировать PHP с найденным патчем.   -  person Luistar15    schedule 15.05.2013
comment
В FreeTDS просто установите tds version = 7.2 в freetds.conf и все заработает!   -  person youngrp    schedule 19.05.2018


Ответы (2)


Проведя небольшое исследование этого, кажется, что pdo_odbc содержит ошибки на 64-битных архитектурах: он построен с 32-битными размерами SQLLEN и SQLULEN. Раньше драйвер Microsoft был построен таким образом, возможно, поэтому PHP последовал его примеру. С тех пор MS начали правильно следовать спецификации ODBC, но, по-видимому, PHP - нет.

Исправление, указанное в вопросе, устраняет одну такую ​​​​проблему в исходном коде PHP, но, по-видимому, не все такие проблемы. Используя драйвер MS и исправленный PHP, я все еще не мог запускать подготовленные операторы.

На самом деле я обнаружил ту же проблему при использовании драйвера Easysoft, и, обсудив с ними проблемы, обнаружил, что виновником является pdo_odbc. Они смогли предоставить мне 64-битный драйвер, созданный с использованием 32-битных размеров, и он отлично работает.

Пока 64-битный PHP не будет исправлен для использования 64-битных размеров SQLLEN и SQLULEN, похоже, что лучшим бесплатным решением является использование 32-битных драйверов PHP и ODBC.

person Richard Turner    schedule 30.08.2013
comment
Для справки: все еще проблема с Ubuntu 14.04 php 5.5.9. Я получаю недопустимое значение символа для спецификации приведения. Обсуждается в connect.microsoft.com/SQLServer/feedback/details/737751/ - person Jim; 05.05.2014
comment
Только что найденный с помощью odbc_connect, odbc_prepare работает с запросами и хранимыми процедурами с драйвером MSSQL 11. - person Jim; 05.05.2014

такая же ошибка здесь:

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)

64-разрядная версия Win7, PHP 5.4.12, SQL Server Express 2012, ODBC 11 для SQL Server

person ikkez    schedule 05.06.2013