Laravel complains about query with duplicate named parameters

两盒软妹~` 提交于 2019-11-28 06:43:27

问题


When I do (in laravel):

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

It says:

SQLSTATE[HY093]: Invalid parameter number (SQL: SELECT * FROM my_table WHERE id = :id || id = :id)

But when I do (in pure 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']);
}

It succeeds. What am I doing wrong?

P.S. Apparently, the query I ran when I encountered the issue was more meaningful.

UPD More or less real query:

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

回答1:


From what I can see it all comes down to mysql being unable to deal with named parameters.

mysqli::prepare:

This parameter can include one or more parameter markers in the SQL statement by embedding question mark (?) characters at the appropriate positions.

pdo::prepare:

You must include a unique parameter marker for each value you wish to pass in to the statement when you call PDOStatement::execute(). You cannot use a named parameter marker of the same name more than once in a prepared statement, unless emulation mode is on.

Laravel has emulation mode disabled by default. One can enable it in config/database.php by adding 'options' => [PDO::ATTR_EMULATE_PREPARES => TRUE] to connection settings. That way you will get the same result as in pure php. Not sure that's a good idea, though.




回答2:


I usually solve that using a CROSS JOIN with a "constant" derived table (subquery in FROM clause). Then I can reuse the parameters as many times as I want.

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


来源:https://stackoverflow.com/questions/39257070/laravel-complains-about-query-with-duplicate-named-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!