SQLSTATE[HY093]:参数号和 PDO::ATTR_EMULATE_PREPARES 无效

Posted

技术标签:

【中文标题】SQLSTATE[HY093]:参数号和 PDO::ATTR_EMULATE_PREPARES 无效【英文标题】:SQLSTATE[HY093]: Invalid parameter number and PDO::ATTR_EMULATE_PREPARES 【发布时间】:2019-02-24 12:12:05 【问题描述】:

在laravel中执行如下查询时

  $result = DB::select(
                'SELECT p.f1 FROM `tab1` m
                INNER JOIN `tab2` p
                ON m.id= p.fk
                WHERE m.good_id = :good_id AND p.good_id = :good_id LIMIT 1',
                ['good_id' => 12]
            );

得到一个错误 SQLSTATE[HY093]: Invalid parameter number.

找到了解决办法。

我们可以添加以下代码

'options' => [
     PDO::ATTR_EMULATE_PREPARES => true,
],

到 config/database.phpmysql 数组。

但是从安全的角度来看,使用它会有什么问题吗? https://github.com/Microsoft/msphpsql/issues/46

上述帖子中提到的问题仍然存在?

【问题讨论】:

【参考方案1】:

是的,该安全问题也适用于您。但是,您的问题还有另一个快速解决方案,不涉及PDO::ATTR_EMULATE_PREPARES

$result = DB::select(
    'SELECT p.f1 FROM `tab1` m
    INNER JOIN `tab2` p
    ON m.id= p.fk
    WHERE m.good_id = :good_id AND p.good_id = :good_id0 LIMIT 1',
            ['good_id' => 12, 'good_id0' => 12]
    );

这增加了 sql 中标识符的数量,并将相同的值放入其中。你也可以优化你的sql,

$result = DB::select(
    'SELECT p.f1 FROM `tab1` m
    INNER JOIN `tab2` p
    ON (m.id= p.fk AND m.good_id = p.good_id)
    WHERE m.good_id = :good_id LIMIT 1',
            ['good_id' => 12]
    );

这将使您的 sql 只需要 1 个标识符。

【讨论】:

以上是关于SQLSTATE[HY093]:参数号和 PDO::ATTR_EMULATE_PREPARES 无效的主要内容,如果未能解决你的问题,请参考以下文章

Pdo - 将值插入数据库错误 SQLSTATE [HY093] [重复]

致命错误:未捕获PDOException:SQLSTATE [HY093]:参数号无效:无参数

PHP PDOException:“SQLSTATE [HY093]:无效参数号”

SQLSTATE[HY093]:参数号无效:参数未定义

SQLSTATE [HY093]:参数号无效:未定义参数 - php

PDOStatement :: execute():SQLSTATE [HY093],批量插入时的奇怪行为