对于看似有效的查询,mysqli prepare失败,并出现SQL语法错误


mysqli prepare fails with SQL syntax error for seemingly valid query

我被这个问题难住了。

我有一些代码可以生成更新查询、准备、绑定它们,然后执行。第一个查询运行成功,但第二个查询的prepare失败。查询非常简单。我特别困惑,因为mysql日志显示了正在准备的查询,而且我可以在mysql中手动执行它。考虑以下代码:

$set = null;
                        foreach($editable as $field => $value) {
                                if(!empty($value))
                                $set .= $field."=?,";
                        }
                        $set = substr($set, 0, -1);
                        // generate the update query based on object data, and execute it
                        $stmt = $this->dbh->stmt_init() or die("stmt_init: ".$this->dbh->error);
                        $stmt->prepare("UPDATE ".$this->table_name."
                                                                 SET ".$set."
                                                                 WHERE ".$whereclause) or die("prepare failed: ".$this->dbh->error." (".$stmt->sqlstate.")");
                        if($stmt->error) die($stmt->error);
                        $this->bindParameters($stmt, $editable);
                        $stmt->execute();
                        $stmt->close();

 function bindParameters(&$statement, &$params) {
                echo "<pre>";
                var_dump($statement);
                echo "</pre>";
                $args   = array();
                // just assume every value is string type
                $args[] = implode('', array_map(function($v) {
                                                                                                return "d";
                                                                                },
                                                                                array_values($params)));
                foreach ($params as $paramName => $value) {
                        $args[] = &$params[$paramName];
                        //$params[$paramName] = null;
                }
                var_dump($args);
                //die();
                call_user_func_array(array(&$statement, 'bind_param'), $args);
        }

第一部分在循环中运行,$editable是字段名称和值的数组$其中Clause始终为"client_id=83"$这个->dbh保存连接对象。此代码适用于第一次更新,但不适用于第二次更新。它正在生成这样的查询:

UPDATE client_rate SET rate=? WHERE client_id=83

它正在创建以下内容:

UPDATE client_rate SET rate=99 WHERE client_id=83
UPDATE client_rate SET rate=165 WHERE client_id=83

第二个是由于语法错误而失败的。mysql日志显示了这些查询,我可以手动运行它们而不会出错。

准确显示的错误是:

prepare failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE client_id=83' at line 3 (42000)

这是我在mysql查询日志中看到的与此相关的内容:

            19954 Query     SELECT * FROM client_rate LIMIT 0
            19954 Query     SELECT * FROM client_rate WHERE client_id=83
            19954 Prepare   UPDATE client_rate
                                                             SET rate=?
                                                             WHERE client_id=83
            19954 Execute   UPDATE client_rate
                                                             SET rate=99
                                                             WHERE client_id=83
            19954 Close stmt
            19954 Query     SELECT * FROM client_rate WHERE client_id=83
            19954 Prepare   UPDATE client_rate
                                                             SET rate=?
                                                             WHERE client_id=83
            19954 Execute   UPDATE client_rate
                                                             SET rate=165
                                                             WHERE client_id=83
            19954 Close stmt

我到底做错了什么,会导致准备检测错误?

更新:当我删除所有的错误检查时,我可以看到DB实际上运行得很好。我只是在我的页面上得到以下几次:

Warning: mysqli_stmt::bind_param(): invalid object or resource mysqli_stmt

有什么明显的东西可能我不见了?

好吧,最后我真的不知道是什么原因造成的。我注意到我的调试代码在试图解决这个问题时真的堆积起来了,所以我恢复了我的工作副本。然后它神秘地开始工作。

我不确定我一开始是怎么打破它的,但现在它奏效了。。。