Php pdo unixOBDC到sqlserver 2008:字符串数据,长度不匹配时执行准备好stmt
问题描述:
我有以下设置:Apache/php 5.3/pdo与odbc与安装的Microsoft SQL Server ODBC驱动程序1.0在服务器上的Linux。试图执行一个语句时Php pdo unixOBDC到sqlserver 2008:字符串数据,长度不匹配时执行准备好stmt
我的脚本上升的错误有以下堆栈跟踪:
(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 and SQL Server 2008: Can't use prepared statements?。但我无法检查它。当我尝试在生产中添加属性时,脚本出现以下错误:
(UTC) 2013-12-16 13:19:44: SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes
有谁知道如何解决此问题?
已更新2013年12月18日
// 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。
答
错误
(UTC) 2013-12-16 13:19:44: SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes
告诉你这行:
$this->_link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
是无效的。相反,这样做:
$driver_options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => FALSE);
if (DB_DRIVER == 'odbc'){ // for unixODBC (production)
$dsn = 'odbc:DRIVER={SQL Server Native Client 11.0};SERVER='. DB_HOST .';PORT='. DB_PORT .';DATABASE='. DB_NAME .';PROTOCOL=TCPIP;';
$this->_link = new PDO($dsn, DB_LOGIN, DB_PASSWD, $driver_options);
}else{ // for sqlsrv (development)
$this->_link = new PDO(
"sqlsrv:Server=" . DB_HOST . "," . DB_PORT . ";Database=" . DB_NAME,
DB_LOGIN,
DB_PASSWD
);
}
不,当我申请$ pdo->的setAttribute(PDO :: ATTR_EMULATE_PREPARES,FALSE)只发生错误; – Eugeny
@Eugeny - 我已经更新了我的答案。您不能使用'setAttribute()'函数,您必须在创建PDO对象时设置该选项。 –
不幸的是,同样的错误。它不允许设置除PDO :: ATTR_ERRMODE之外的任何属性,即使在创建PDO时也是如此。 – Eugeny