Pie*_*yle 6 php sql-server odbc unixodbc freetds
我正在使用以下设置从PHP应用程序访问MS-SQL数据库
非参数化查询工作正常.唯一的问题是被迫关闭单个结果语句(使用PDOStatment :: closeCursor)以避免"0 [FreeTDS] [SQL Server]无效游标状态(SQLSTATE = 24000)"错误.
但是我遇到了类型绑定参数的一个主要问题.使用这样的代码时:
$stmt = $PDO->prepare('INSERT INTO table (column1, column2) VALUES (:foo, :bar');
$stmt->bindValue(':foo', 21, PDO::PARAM_INT);
$stmt->bindValue(':bar', 42, PDO::PARAM_INT);
$stmt->execute():
if (!$stmt->execute()) {
var_dump($stmt->errorInfo();
}
Run Code Online (Sandbox Code Playgroud)
两列都是INT.我得到一个"206 [FreeTDS] [SQL Server]操作数类型冲突:文本与int [SQLSTATE = 22018]"错误不兼容.
在unixODBC日志中,我得到类似的东西
[ODBC][26251][SQLDescribeParam.c][175]
Entry:
Statement = 0x2b73c849fb80
Parameter Number = 1
SQL Type = 0x7fff9c89e15e
Param Def = 0x7fff9c89e154
Scale = 0x7fff9c89e15c
Nullable = 0x7fff9c89e15a
[ODBC][26251][SQLDescribeParam.c][276]Error: IM001
[ODBC][26251][SQLBindParameter.c][193]
Entry:
Statement = 0x2b73c849fb80
Param Number = 1
Param Type = 1
C Type = 1 SQL_C_CHAR
SQL Type = -1 SQL_LONGVARCHAR
Col Def = 4000
Scale = 5
Rgb Value = 0x2b73c941f890
Value Max = 0
StrLen Or Ind = 0x2b73c93fa1b0
[ODBC][26251][SQLBindParameter.c][339]
Exit:[SQL_SUCCESS]
Run Code Online (Sandbox Code Playgroud)
我对日志的理解是unixODBC正在尝试使用正确的类型绑定参数.但FreeTDS不支持该功能(IM001是'驱动程序不支持此功能').所以unixODBC继续没有正确打字.
有人可以确认这个诊断,或者更好的是,FreeTDS中的类型绑定参数的已知问题?如果是,他们是否使用PHP PDO工作,我可以配置它吗?
在FreeTDS邮件列表中,我得到了FreeTDS不支持SQLDescribeParam的确认.但是当不支持SQLDescribeParam时,PDO_ODBC应该归咎于使用LONGVARCHAR(即文本).
相同的代码在带有PDO ODBC的Windows工作站上运行(PHP版本5.2.9,ODBC库Win32)
此问题的解决方法是将每个参数视为LONGVARCHAR并在查询中使用显式类型转换.MS SQL Server仅支持LONGVARCHAR =>*CHAR转换.要转换,我不得不使用像CAST(CAST(:number AS varchar) AS INTEGER)或的东西CAST(CAST(:birthdate AS varchar) AS datetime).这是糟糕的,丑陋的,可能是一场表演,但它确实有效.