【问题标题】:PHP PDO Invalid parameter number: parameter was not defined using Q-mark parametersPHP PDO 参数号无效:未使用 Q 标记参数定义参数
【发布时间】:2012-05-25 04:32:15
【问题描述】:

编辑:标题中不能有“问题”一词。 Q-mark的意思是“问号”

编辑 2:意识到我应该从虚拟客户记录中删除我的个人联系信息

我正在尝试制作一些基本功能来减少对最近项目的维护。其中包括以下简单功能,因此我可以在以后向数据库添加列,而无需更改我的更新查询:

function update( $table, $fields ) {
    global $db; // A slightly modified PDO object
    if( count( $fields ) > 0 ) {
        $query = "UPDATE `" . $table . "` SET ";
        foreach( $customer as $key => $value ) {
            $query .= "`" . $key . "` = ?, ";
        }
        $query = substr( $query, 0, -2 );
        $query .= " WHERE `id` = " . $_REQUEST['id'];
        $db->prepare( $query );
        $db->execute( $fields );
    } else { return true; }
}

当我传递一个或两个字段时,这个函数可以工作,但是当我尝试传递更多字段时它失败了。这是我收到的查询、$fields 的值和错误:

查询:

string 'UPDATE `customers` SET `5v` = ?, `contactaddress` = ?, `contactaddress2` = ?, `contactcity` = ?, `contactemail` = ?, `contactname` = ?, `contactphone` = ?, `contactstate` = ?, `contactzip` = ?, `corrugated` = ?, `name` = ?, `permalok` = ?, `residential` = ?, `secureseam` = ?, `tax` = ? WHERE `id` = 1' (length=301)

$字段:

array
  '5v' => string '120' (length=3)
  'contactaddress' => string '999 Street Dr' (length=13)
  'contactaddress2' => string 'Apt 2' (length=7)
  'contactcity' => string 'City' (length=9)
  'contactemail' => string 'steven.abarnett@gmail.com' (length=25)
  'contactname' => string 'Steven Barnett' (length=14)
  'contactphone' => string '(555) 555-5555' (length=14)
  'contactstate' => string 'KY' (length=2)
  'contactzip' => string '55555' (length=5)
  'corrugated' => string '90' (length=2)
  'name' => string 'Steven's Metals' (length=15)
  'permalok' => string '130' (length=3)
  'residential' => string '100' (length=3)
  'secureseam' => string '130' (length=3)
  'tax' => string '6' (length=1)

错误:

string 'Statement execution failed: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined' (length=96)

谷歌搜索这个错误,这听起来像是 named 参数的问题,而不是 question-mark 参数。为什么会出现此错误?

更新

我一直在继续调试和实验,跟踪错误我发现不是语句执行失败,而是尝试在之后获取结果。

在我修改后的 PDO 对象中,我的 execute() 方法中有以下代码:

    // Load from database
    try {
        $this->stmt->execute( $args );
        $this->lastid = $this->dbh->lastInsertId();
        $this->data = $this->stmt->fetchAll();
    } catch (PDOException $e) {
        $this->error = 'Statement execution failed: ' . $e->getMessage();
        return false;
    }

try{} 部分的每一行之间放置echo 语句表明前两行运行顺利,但第三行抛出异常。

当我调用PDOStatement::fetchAll() 时,我的查询是否会因一般错误而失败?

最终更新:

事实证明PDO and Mysql haven't been playing nicely for 6 years。一般的解决方案似乎是在每次调用PDOStatement::execute() 后取消设置 PDOStatement 对象,但这对我不起作用。问题源于 MySQL 一次只能打开一个指向记录集中记录的游标,因此另一种建议的解决方案是使用PDOStatement::fetchAll() 而不是PDOStatement::fetch() 或调用PDOStatement::closeCusor()。同样,这对我不起作用。我的问题来自 MySQL 的某些安装,它会在 INSERTUPDATEDELETE 查询期间创建一个游标(所有这些都没有返回数据),因为它指向空数据,所以无法关闭。

我的解决方案是仅在运行返回数据的查询时调用 PDOStatement::fetchAll()。我有一个 queryhash 变量,用于缓存(我对 PDO 类所做的重大修改),对于这三种查询类型,它设置为 false(因为您需要将查询发送到数据库而不是推迟到缓存)。我只是修改了我的 execute() 函数来检查这个变量,如果它没有设置为 false,则只调用 fetchAll()

【问题讨论】:

  • id = $_REQUEST['id'] 也需要准备
  • @Pills:这没有帮助。当我更改为数字键时,仍然出现 HY000 一般错误。

标签: php mysql pdo


【解决方案1】:

您应该使用索引数组而不是关联数组。

array(
    '120',
    '750 Shaker Dr',
    'Apt 505',
    'Lexington', 
    'steven.abarnett@gmail.com', 
    'Steven Barnett', 
    '(859) 402-7760', 
    'KY',
    '40504', 
    '90',
    "Steven's Metals",
    '130',
    '100',
    '130',
    '6'
)

【讨论】:

  • array_values 会让这一切变得非常简单
  • 现在出现新错误。 string 'Statement execution failed: SQLSTATE[HY000]: General error' (length=58)
  • 发现新错误稍微复杂一些(也修复了它)——尽管使用array_values 确实解决了第一个错误,因此接受了ergo 答案。我将在问题中添加一条注释来描述我是如何修复新错误的。
【解决方案2】:

从 PHP 5.2 开始,传递给 execute() 的数组必须与语句字符串中的键具有相同的键。由于您使用了?,因此 PDO 期望传递给execute() 的数字索引数组而不是关联数组。在构造 $fields 数组时,只需以正确的顺序将每个值附加到它上面,不要指定键。或者,将它们提取到带有array_values() 的数字索引数组中:

$db->execute(array_values($fields));

docs on PDOStatement::execute()

5.2.0 input_parameters 中的键必须与 SQL 中声明的键匹配。在 PHP 5.2.0 之前,这被忽略了。

【讨论】:

  • 这解释了为什么我以前从未遇到过这个问题。上周从 5.0.4 更新。在我的其他评论中,使用 array_values() 给了我一个新错误:string 'Statement execution failed: SQLSTATE[HY000]: General error' (length=58)
猜你喜欢
  • 1970-01-01
  • 2016-03-13
  • 2016-12-15
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多