我有一个名为'cities'的表,其中有两个名为lat,lng的字段。现在我想使用用户提供的lat,lng搜索100英里内的城市。我的代码ID如下..
$lat = $latLng['lat']; // user provide lat
$lng = $latLng['lng']; // user provide lat
$facilities = $this->City->find('all', array(
'fields' => array('(((acos(sin((".$lat."*pi()/180)) *
sin((`City.lat`*pi()/180))+cos((".$lat."*pi()/180)) *
cos((`City.lat`*pi()/180)) * cos(((".$lng."- `City.lng`)*
pi()/180))))*180/pi())*60*1.1515
) as distance', 'City.name', 'City.description' ),
'conditions' => array('City.distance' < 20)
));
它给出错误“错误:SQLSTATE [42S22]:未找到列:1054'字段列表'中的未知列'City.lat'”
答案 0 :(得分:1)
首先,如果你没有使用casted / sanitized /转义用户输入,那么你所拥有的是一个很好的SQL注入漏洞,字段不会像例如条件那样被转义。 请记住,永远不要直接将用户数据插入查询中!
该列未知,因为它实际上并不存在,您将City.lng
作为列名,而不只是lng
和表名City
,为了做到这一点,你必须分别正确引用这两个,即
`City`.`lng`
我不知道您使用的是哪个DBMS,但对于MySQL,Postgre以及SQL Server都是如此。您无法在distance
条件中使用汇总的WHERE
列,您必须使用HAVING
,或者再次在WHERE
子句中重新引入相同的计算(这是virtual fields会做的事情。
HAVING
子句可以像这样插入:
'conditions' => [
// ...
'1=1 HAVING distance < 20'
]
另请注意,您必须使用完全别名,即仅distance
,而不是City.distance
,就像条件一样(语法无效,'City.distance' < 20
是一个表达式评估为true
)。