服务器错误MySQL错误-1064


Server error MySQL Error - 1064

作为国内最好的程序员,我想我会问这个问题,希望有人能发现错误,或者告诉我我做错了。

我有一个Flash Builder网站,它试图创建一个搜索功能来搜索我的MYSQL数据库,然后返回结果。

我包含了非空部分,以防用户没有在相关变量中键入任何数据。

但是我得到了这个错误原因:服务器错误MySQL错误-1064:您的SQL语法有错误;查看与MySQL服务器版本对应的手册,了解在第1#0行的"wells AND sex LIKE female"附近使用的正确语法

这是代码

public function searchClients($fname, $lname, $country, $town, $sex) {
$SQLStatment = "SELECT id, fname, lname, sex, country, town, dateofbirth, monthofbirth, yearofbirth FROM $this->tablename";
$WhereClause = "";
$where =" Where ";
if($fname != "NULL") {
            $WhereClause.= 'Fname LIKE '.$fname;
}         
if($lname != "NULL") {
 if($WhereClause != "") 
 {  
            $WhereClause.= ' AND lname LIKE ' .$lname;
 }
 else
 {
        $WhereClause = 'lname LIKE ' .$lname;
 }
}
if($country != "NULL") {     
if($WhereClause != "") 
 {  
            $WhereClause.= ' AND country LIKE ' .$country;
 }
 else 
 {
        $WhereClause = 'country LIKE ' .$country;
 }
}
if($town != "NULL") {
 if($WhereClause != "") 
 {  
            $WhereClause.= ' AND town LIKE ' .$town;
 }
 else
 {
        $WhereClause = 'town LIKE ' .$town;
 }
}    
if($sex != "NULL") {
 if($WhereClause != "")
 {  
            $WhereClause.= ' AND sex LIKE ' .$sex;
 }
 else
 {
        $WhereClause = 'sex LIKE ' .$sex;
 }
}    
$SQLStatment.= $where;
$SQLStatment.= $WhereClause;
    $stmt = mysqli_prepare($this->connection, $SQLStatment);
    $this->throwExceptionOnError();
     mysqli_stmt_execute($stmt);
    $this->throwExceptionOnError();
    $rows = array();
    mysqli_stmt_bind_result($stmt, $row->ID, $row->fname, $row->lname,  $row->sex, $row->country, $row->town, $row->dateofbirth, $row->monthofbirth, $row->yearofbirth);
    while (mysqli_stmt_fetch($stmt)) {
      $row->fname = ucfirst(substr($row->fname,0,1));
      $row->lname = ucfirst($row->lname);
       $row->town = ucfirst($row->town);
      $row->lname = (($row->fname) . " " . ($row->lname));
      $row->yearofbirth = GetAge($row->dateofbirth. '-' .$row->monthofbirth. '-' .$row->yearofbirth);
      $row->Pic_loc = "";
      $row->Pic_loc= "IMAGES/".($row->ID)."/image01.jpg";
      $rows[] = $row;
      $row = new stdClass();
      mysqli_stmt_bind_result($stmt, $row->ID, $row->fname, $row->lname,  $row->sex, $row->country, $row->town, $row->dateofbirth, $row->monthofbirth, $row->yearofbirth);
    }
    mysqli_stmt_free_result($stmt);
    mysqli_close($this->connection);
    return $rows;
}

它在我看来不错,但不起作用,有什么建议吗?在代码中指出它的呻吟是

if($town != "NULL") {
 if($WhereClause != "") 
 {  
            $WhereClause.= ' AND town LIKE ' .$town;
 }
 else
 {
        $WhereClause = 'town LIKE ' .$town;
 }
}    
if($sex != "NULL") {
 if($WhereClause != "")
 {  
            $WhereClause.= ' AND sex LIKE ' .$sex;
 }
 else
 {
        $WhereClause = 'sex LIKE ' .$sex;
 }
}    

只是觉得很奇怪,它没有抱怨其他三个if条款,而是抱怨最后两个。

where子句应该是这样的:

$WhereClause .= ' AND sex LIKE "' . mysql_escape_string($sex).'"';

您可以使用准备好的语句/PDO来简化代码并保护应用程序不受SQL注入的影响

您的字符串应该加引号。对where子句进行以下更改:

if($town != "NULL") {
     if($WhereClause != "") 
     {  
                $WhereClause.= ' AND town LIKE "' .mysql_escape_string($town).'"';
     }
     else
     {
            $WhereClause = 'town LIKE "' .mysql_escape_string($town).'"';
     }
    }    
    if($sex != "NULL") {
     if($WhereClause != "")
     {  
                $WhereClause.= ' AND sex LIKE "' .$sex.'"';
     }
     else
     {
            $WhereClause = ' sex LIKE "' .$sex.'"';
     }
    }  

顺便说一句,你应该在你的值周围使用百分比符号

首先,一个调试技巧——当你在动态构建语句时,遇到一个无法立即解决的SQL错误,首先要做的就是打印出构建的语句(请在你未来的SO文章中包括它)。部分看起来像:

SELECT … lname LIKE wells AND sex LIKE female …

从中,你可以看到你的值周围的引号缺失了——应该是:

SELECT … lname LIKE 'wells' AND sex LIKE 'female' … -- quoting non-numeric is NOT optional in SQL

所以,为了运行这个,你可以添加单引号。但仍然存在两个问题,还有第三个潜在问题。

  1. 这仍然不起作用。我假设通过使用LIKE而不是=,您想要进行子字符串匹配。所以你需要在你的值周围加上百分比符号:lname LIKE '%wells%'
  2. 您已经在使用准备好的语句,您真的应该使用占位符(例如lname LIKE ?)构建查询,然后用这种方式填充。这将为您处理转义,防止SQL注入

潜在的第三个问题是,使用LIKE进行子字符串匹配的性能非常糟糕。这种类型的匹配可以而不是使用索引。您正在进行全表扫描。使用全面的搜索解决方案(Sphinx、全文等)可以解决这个问题(但可能会增加更多的工作)。