当我这样做时(在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']);
}
成功了。我做错了什么?
P.S。显然,我遇到问题时遇到的查询更有意义。
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
答案 0 :(得分:2)
从我所看到的一切都归结为mysql
无法处理命名参数。
此参数可以在SQL语句中包含一个或多个参数标记,方法是在适当的位置嵌入问号(?)字符。
在调用PDOStatement :: execute()时,必须为要传递给语句的每个值包含唯一的参数标记。除非启用了仿真模式,否则不能在预准备语句中多次使用同名的命名参数标记。
Laravel具有仿真模式disabled by default。可以通过将config/database.php
添加到连接设置,在'options' => [PDO::ATTR_EMULATE_PREPARES => TRUE]
中启用它。这样你就会得到与纯php相同的结果。但不确定这是个好主意。
答案 1 :(得分:0)
我通常使用带有“恒定”派生表(在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