Jef*_*ett 24 php sql-server odbc pdo prepared-statement
注意:我已将此问题缩小到专门的PDO,因为我能够使用odbc_*函数成功准备和执行语句.
为什么我不能将此参数绑定到PDO预处理语句?
这有效:
$mssqldriver = 'ODBC Driver 13 for SQL Server';
$pdoDB = new PDO("odbc:Driver=$mssqldriver;Server=$hostname;Database=$dbname", $username, $password);
$pdoDB->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "SELECT 'value' AS col where 'this' = 'this'";
$stmt = $pdoDB->prepare($sql);
$params = [];
$stmt->execute($params);
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Array ( [col] => value [0] => value )
不起作用:
$sql = "SELECT 'value' AS col where 'this' = ?";
$stmt = $pdoDB->prepare($sql);
$params = ['this'];
$stmt->execute($params);
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
Web服务器在Linux Ubuntu 14.04上运行PHP 5.5.9,带有用于SQL Server的ODBC驱动程序13,并在Windows Server 2012上连接到Microsoft SQL Server 2012
这是完整的错误:
Run Code Online (Sandbox Code Playgroud)Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[22001]: String data, right truncated: 0 [Microsoft][ODBC Driver 13 for SQL Server] String data, right truncation (SQLExecute[0] at /build/buildd/php5-5.5.9+dfsg/ext/pdo_odbc/odbc_stmt.c:254)' in /var/www/scratch.php:46 Stack trace: #0 /var/www/scratch.php(46): PDOStatement->execute(Array) #1 {main} thrown in /var/www/scratch.php on line 46
我也尝试过设置:
$pdoDB->setAttribute( PDO::ATTR_EMULATE_PREPARES, true );
Run Code Online (Sandbox Code Playgroud)
并使用命名参数:
$sql = "SELECT 'value' AS col where 'this' = :myVal";
$stmt = $pdoDB->prepare($sql);
$params = ['myVal' => 'this'];
$stmt->execute($params);
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
即使有明确的冒号:
$params = [':myVal' => 'this'];
Run Code Online (Sandbox Code Playgroud)
$sql = "SELECT 'value' AS col where 'this' = ?";
$stmt = $pdoDB->prepare($sql);
$param = 'this';
$stmt->bindParam(1, $param);
$stmt->execute();
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
与命名参数一样:
$sql = "SELECT 'value' AS col where 'this' = :myVal";
$stmt = $pdoDB->prepare($sql);
$param = 'this';
$stmt->bindParam(':myVal', $param, PDO::PARAM_STR);
$stmt->execute();
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
如果我尝试明确设置长度:
$stmt->bindParam(':myVal', $param, PDO::PARAM_STR, 4);
Run Code Online (Sandbox Code Playgroud)
我收到奖金错误:
Run Code Online (Sandbox Code Playgroud)Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 102 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server] Incorrect syntax near 'OUTPUT'.
是的,所有这些都是一个没有表格的简单例子,因此您可以轻松地重现它,但是为了确定,我实际上已经尝试了一个真正的表格.
CREATE TABLE myTable (
id INT IDENTITY PRIMARY KEY,
val NVARCHAR(255)
);
INSERT INTO myTable (val) VALUES ('hello world');
Run Code Online (Sandbox Code Playgroud)
作品:
$sql = "SELECT * FROM myTable WHERE val = 'hello world'";
$stmt = $pdoDB->prepare($sql);
$params = [];
$stmt->execute($params);
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Array ( [id] => 1 [0] => 1 [val] => hello world [1] => hello world )
不起作用:
$sql = "SELECT * FROM myTable WHERE val = ?";
$stmt = $pdoDB->prepare($sql);
$params = ['hello world'];
$stmt->execute($params);
print_r($stmt->fetch());
Run Code Online (Sandbox Code Playgroud)
所有路径都会导致相同的错误:
字符串数据,右截断
rev*_*evo 22
这是一个PDO_ODBC
64位不兼容问题(#61777,#64824),毫无疑问,你使用的是64位版本,它不允许你绑定参数.
它有一个补丁,最初包含在5.6版本中:
此错误也在#61777中引用, 并且仍然存在于5.5分支的最新稳定版本中.我已经看到这个问题已经存在两张票了,我只是通过github提交这些更改作为提醒,这对任何使用
PDO_ODBC
x64版本的人来说都是一个严重的问题.
PDO_ODBC
什么问题?通过查看其中一个推荐的补丁:
diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c
index 8b0ccf3..1d275cd 100644
--- a/ext/pdo_odbc/odbc_stmt.c
+++ b/ext/pdo_odbc/odbc_stmt.c
@@ -551,7 +551,7 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
struct pdo_column_data *col = &stmt->columns[colno];
RETCODE rc;
SWORD colnamelen;
- SDWORD colsize;
+ SQLULEN colsize;
SQLLEN displaysize;
Run Code Online (Sandbox Code Playgroud)
我们看到,已经改变的唯一事情是SDWORD
取代有新的ODBC类型(16位带符号整数)SQLULEN
是在64位ODBC应用64个比特,并在一个32位ODBC应用程序32位.
我认为提交者不知道colsize
数据类型,因为在下一行SQLLEN
中定义得当.
odbc_*
功能作为工作解决方案. 归档时间: |
|
查看次数: |
2903 次 |
最近记录: |