添加时出现以下错误: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
我试过的东西:
$sql->bindValue(':start', (int) 1, PDO:PARAM_INT);
- 不要去。有什么建议吗?我使用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.
答案 0 :(得分:2)
通常,占位符的:start
表示法既不是标准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
表示法转换为?
,在这种情况下我们会遇到不同的问题。但除非您确定:name
符号有效,否则......
不确定的一个原因是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
设置为某个类似值的情况下运行代码,那么您应该在名称如{的文件中找到发送到服务器的内容(除了连接设置之外)的记录。 {1}}。数字模式有点变化。然后,您可以在该文件上运行/tmp/your_sub_dir/check_21484_0_aedc1e0
程序,并查看PDO发送到服务器的内容。这将是一种非常快速的方法,可以确定PDO或Informix中是否存在错误。
例如,我从sqliprint
得到的部分输出是:
sqliprint
您可以非常清楚地看到发送的SQL语句。如果您没有看到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
占位符,则上游存在问题;要么Informix的PDO驱动程序没有正常工作,要么被误用。如果您看到?
占位符,我们会遇到一系列不同的问题,但如果问题出现,我会感到惊讶。
SQLIDEBUG机制中唯一需要注意的是,您需要在连接到数据库的任何进程的环境中设置环境变量。对于独立的ESQL / C程序,这是微不足道的。如果您正在使用Web服务器和PHP,这可能会更棘手 - 但可以完成。