【问题标题】:Laravel complains about query with duplicate named parametersLaravel 抱怨带有重复命名参数的查询
【发布时间】:2017-01-08 11:37:45
【问题描述】:

当我这样做时(在 laravel 中):

<?php
\DB::select('SELECT * FROM my_table WHERE id = :id || id = :id', [
    'id' => 1,
]);

上面写着:

SQLSTATE[HY093]: 参数号无效(SQL: SELECT * FROM my_table WHERE id = :id || id = :id)

但是当我这样做时(在纯 php 中):

<?php
$dbh = new PDO('mysql:dbname=...', '...', '...');
$stmt = $dbh->prepare('SELECT * FROM my_table WHERE id = :id || id = :id');
$r = $stmt->execute([
    'id' => 1,
]);
while ($row = $stmt->fetch()) {
    var_dump($row['id']);
}

成功了。我做错了什么?

附:显然,我遇到问题时运行的查询更有意义。

UPD或多或少真实的查询:

SELECT id
FROM objects
WHERE ACOS(
    SIN(RADIANS(lat)) * SIN(RADIANS(:lat))
    + COS(RADIANS(lat)) * COS(RADIANS(:lat)) * COS(RADIANS(:lng - lng))
) * 6371 < 10

【问题讨论】:

  • 在查询中最好使用OR 而不是||
  • 但是为什么id = :id 两次呢?与OR 连接?
  • 就像我说的,查询有点牵扯,比如... ACOS(SIN(RADIANS(lat)) * SIN(RADIANS(:lat)) + COS(RADIANS(lat)) * COS(RADIANS(:lat)) * COS(RADIANS(:lng - lng))) * 6371 ...,你可以在这里看到:lat参数。

标签: php mysql sql laravel query-builder


【解决方案1】:

我通常使用带有“常量”派生表(FROM 子句中的子查询)的 CROSS JOIN 来解决这个问题。然后我可以根据需要多次重复使用这些参数。

SELECT id
FROM objects o
CROSS JOIN (SELECT :lat as lat, :lng as lng) params
WHERE ACOS(
    SIN(RADIANS(o.lat)) * SIN(RADIANS(params.lat))
    + COS(RADIANS(o.lat)) * COS(RADIANS(params.lat)) * COS(RADIANS(params.lng - o.lng))
) * 6371 < 10

【讨论】:

  • 交叉连接有什么性能缺陷吗?
  • @IjasAmeenudeen - 在这种情况下不是,因为“常量”表只有一行。与仅在 WHERE 子句中重复 lat 和 lng 的值相比,我认为您无法衡量任何性能差异。
【解决方案2】:

据我所知,这一切都归结为mysql 无法处理命名参数。

mysqli::prepare:

通过在适当的位置嵌入问号 (?) 字符,此参数可以在 SQL 语句中包含一个或多个参数标记。

pdo::prepare:

当您调用 PDOStatement::execute() 时,您必须为希望传递给语句的每个值包含一个唯一的参数标记。除非打开了仿真模式,否则您不能在准备好的语句中多次使用同名的命名参数标记。

Laravel 有模拟模式 disabled by default。可以通过在连接设置中添加'options' =&gt; [PDO::ATTR_EMULATE_PREPARES =&gt; TRUE]config/database.php 中启用它。这样,您将获得与纯 php 相同的结果。不过,不确定这是个好主意。

【讨论】:

    猜你喜欢
    • 2021-07-16
    • 1970-01-01
    • 2012-10-13
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    相关资源
    最近更新 更多