添加时出现以下错误:start作为要跳过的参数.我知道如果我硬编码SKIP / NEXT值并且:customerID保持不变,则SQL查询有效.如果我删除了:start子句并将其保留为SKIP 1 FIRST 5 … WHERE t1.customer_num =:customerID …它的工作正常.我无法找到错误发生的原因.
错误
exception 'PDOException' with message 'SQLSTATE[HY004]: Invalid SQL data type: -11064 [Informix][Informix ODBC Driver]SQL data type out of range
我试过的东西:
>使用BindParam而不是BindValue通过引用绑定参数.
>使用PDO_STR尝试绑定:以字符串形式开始.没有成功.
>硬编码值:从SQL查询本身开始.这有效.
>使用$sql-> bindValue(‘:start’,(int)1,PDO:PARAM_INT); – 不行.
>首先通过分配PHP变量来尝试数字4,结果相同.
有什么建议?我使用PDO连接器使用PHP 5.3.(最新的东西)和Informix 11.同样,它仅适用于customerID,但不适用于:start并返回上述错误.
$sql = null;
$sql= $conn->prepare('SELECT SKIP :start FIRST 5 TRIM(loc_esi_id) FROM customer t1,customer_ts_data t2 WHERE t1.customer_num = :customerID AND t1.customer_num = t2.customer_num');
//Bind values to parameters(by value)
$sql->bindValue(':start', $start ,PDO::PARAM_INT);
$sql->bindValue(':customerID', $customerID, PDO::PARAM_INT);
//$sql->bindParam(':count',$count,PDO::PARAM_INT);
$results = null;
try{
$sql->execute();
$results = $sql->fetchAll();
} catch (PDOException $e) {
//Error Handling, etc.
最佳答案 通常,占位符的开始表示法既不是标准SQL语法也不是(本机)Informix语法.你需要使用?对于占位符,因此:
$sql= $conn->prepare('SELECT SKIP ? FIRST 5 TRIM(loc_esi_id)
FROM customer t1
JOIN customer_ts_data t2 ON t1.customer_num = t2.customer_num
WHERE t1.customer_num = ? AND ');
(如果这一切都需要在PHP中的一行,我为了可读性而为了准备就行而道歉).
现在,PDO系统有可能将:start符号转换为?自动,在这种情况下,我们有一个不同的问题.但除非你确定:名称符号有效,…
不确定的一个原因是bindValue()调用似乎需要名称,而不是一个数字?可能需要.您的代码错误检查了bindValue()调用吗?
这个ESQL / C代码工作,产生我期望的输出.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
$char *dbase = "stores";
$int num_skip = 3;
$int num_fetch = 5;
if (argc > 2)
{
fprintf(stderr, "Usage: %s [dbase]\n", argv[0]);
exit(1);
}
if (argc == 2)
dbase = argv[1];
exec sql whenever error stop;
exec sql connect to :dbase;
exec sql prepare p from "select skip ? first ? tabid, tabname from informix.systables";
exec sql declare c cursor for p;
exec sql open c using :num_skip, :num_fetch;
while (sqlca.sqlcode == 0)
{
$int4 tabid;
$varchar tabname[129];
exec sql fetch c into :tabid, :tabname;
if (sqlca.sqlcode != 0)
break;
printf("%d: %s\n", tabid, tabname);
}
exec sql close c;
exec sql free c;
exec sql free p;
exec sql disconnect all;
return 0;
}
产量
4: systabauth
5: syscolauth
6: sysviews
7: sysusers
8: sysdepend
这表明如果正确使用占位符表示法,则可以使用SKIP和FIRST参数.
如果你找不到使用PDO的方法,你可能会遇到错误.如果您可以使用环境变量SQLIDEBUG = 2:/ tmp / your_sub_dir / check设置为某个类似的值来运行您的代码,那么您应该找到一个文件的记录,该文件包含发送到服务器的内容(除了连接设置)一个名称,如/ tmp / your_sub_dir / check_21484_0_aedc1e0.数字模式有点变化.然后,您可以在该文件上运行sqliprint程序,并查看PDO发送到服务器的内容.这将是一种确定PDO或Informix是否存在错误的快速方法.
例如,我从sqliprint获得的部分输出是:
C->S (20) Time: 2012-05-29 17:55:08.65225
SQ_CONNECT
"stores" [6]
"stores" [6]
C->S (72) Time: 2012-05-29 17:55:08.65239
SQ_PREPARE
# values: 2
CMD.....: "select skip ? first ? tabid, tabname from informix.systables" [60]
SQ_NDESCRIBE
SQ_WANTDONE
SQ_EOT
您可以非常清楚地看到发送的SQL语句.如果你没有看到?占位符,那么上游就有问题;要么Informix的PDO驱动程序没有正常工作,要么被误用.如果你看到了?占位符,我们会遇到一系列不同的问题,但如果这就是问题,我会感到惊讶.
SQLIDEBUG机制中唯一需要注意的是,您需要在连接到数据库的任何进程的环境中设置环境变量.对于独立的ESQL / C程序,这是微不足道的.如果您正在浏览Web服务器和PHP,这可能会更棘手 – 但它可以完成.