Informix的变量绑定返回错误

时间:2012-05-29 16:55:44

标签: php pdo 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

我试过的东西:

  1. 使用BindParam而不是BindValue通过引用绑定参数。
  2. 使用PDO_STR尝试绑定:以字符串形式开始。没有成功。
  3. 硬编码值:从SQL查询本身开始。这很有效。
  4. 使用$sql->bindValue(':start', (int) 1, PDO:PARAM_INT); - 不要去。
  5. 首先通过分配PHP变量来尝试数字4,结果相同。
  6. 有什么建议吗?我使用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.
    

1 个答案:

答案 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,这可能会更棘手 - 但可以完成。