php – Informix的变量绑定返回错误

添加时出现以下错误: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,这可能会更棘手 – 但它可以完成.

点赞