У меня следующая установка: Apache/php 5.3/pdo с odbc с установленным драйвером ODBC Microsoft SQL Server 1.0 для Linux на сервере.
Мой сценарий вызывает ошибку со следующей трассировкой стека при попытке выполнить оператор:
(UTC) 2013-12-16 12:07:40: Thrown exception log ->
'Error message: SQLSTATE[22026]: String data, length mismatch: 0 [Microsoft][SQL Server Native Client 11.0]String data, length mismatch (SQLExecute[0] at /tmp/pear/temp/PDO_ODBC/odbc_stmt.c:133)
Arisen in Core_Db->select(array (
0 =>
'SELECT *
FROM TMS.dbo.TEST_user
WHERE email = ? AND status_id = ?',
1 =>
array (
0 => '[email protected]',
1 => 2
),
))
Для тестирования я использую php 5.3 на окнах с pdo sqlsrv, и там ничего не пошло не так.
Код подключения
// for unixODBC (production)
if (DB_DRIVER == 'odbc') {
$this->_link = new PDO(
"odbc:DRIVER={SQL Server Native Client 11.0};SERVER=" . DB_HOST . ";"
. "PORT=" . DB_PORT . ";DATABASE=" . DB_NAME . ";PROTOCOL=TCPIP;UID=" . DB_LOGIN . ";"
. "PWD=" . DB_PASSWD . ";"
);
// for sqlsrv (development)
} else {
$this->_link = new PDO(
"sqlsrv:Server=" . DB_HOST . "," . DB_PORT . ";Database=" . DB_NAME,
DB_LOGIN,
DB_PASSWD
);
}
$this->_link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Есть некоторые рекомендации по этой проблеме: ODBC и SQL Server 2008: Нельзя использовать подготовленные операторы?. Но я не могу это проверить. Когда я пытаюсь добавить атрибут в производство, скрипт выдает следующую ошибку:
(UTC) 2013-12-16 13:19:44: SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes
Кто-нибудь знает, как решить эту проблему?
ОБНОВЛЕНО 18 декабря 2013 г.
// unixODBC connection
$this->_link = new PDO(
"odbc:DRIVER={SQL Server Native Client 11.0};SERVER=xxx.xxx.xxx.xxx;"
. "PORT=1433;DATABASE=TMS;PROTOCOL=TCPIP;",
DB_LOGIN,
DB_PASSWD,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // this attr is recognized by ODBC
PDO::ATTR_EMULATE_PREPARES => false // but if this is added ODBC throws PDOException with message "driver does not support setting attributes"
)
);
Передача строки из ODBC в клиент приводит к повреждению строки при использовании подготовленного оператора. Так что я только предполагаю, что дело в PDO::ATTR_EMULATE_PREPARES.