-2

我用一个方法构建 SQL 查询,然后返回并使用它。

$query = $this->buildSearchQuery($searchParams);            
return $this->db->query($query);

不幸的是,这给了我一个错误:

SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在 ''SELECT * FROM Candidate WHERE firstname = ? AND surname = ?','Dante', 'Hickman' 在第 1 行

我正在搜索它,因为这看起来像以前构建查询的脚本的 SQL 语法失败,所以我做了简单的事情,我在使用它之前转储了这个 $query。

转储返回这个:

"'SELECT * FROM candidates WHERE firstname = ? AND surname = ?','Dante', 'Hickman'" (81)

这是正确的,带有 81 个字符的字符串。在此之后,我尝试将其放入原始查询而不是变量,它看起来像这样:

return $this->db->query('SELECT * FROM candidates WHERE firstname = ? AND surname = ?','Dante', 'Hickman'); 

这个 secod 脚本运行正确,所以它看起来查询是正确构建的,但仍然是错误的。我错过了什么?

我希望有任何建议可以帮助我解决这个问题。

ps 该查询的语法来自 nette 框架,但系统应该相同。

编辑:添加 buildSearchQuery()

function buildSearchQuery($searchParams)
    {
        $column = "";
        $values = "";
        $col = "";
        $i=0;
        // Trim to make sure user doesn't enter space there
        if((trim($searchParams->firstname)))
        {
            $column .= "firstname,";
            $i++;
        }
        if((trim($searchParams->surname)))
        {
            $column .= "surname,";  
            $i++;
        }

        if((trim($searchParams->specialization)))
        {
            $column .= "specialization,";   
            $i++;
        }           
        if($searchParams->english !== NULL)
        {
            $column .= "english,";
            $i++;
        }           
        if($searchParams->german !== NULL)
        {
            $column .= "german,";
            $i++;
        }           
        if($searchParams->russian !== NULL)
        {
            $column .= "russian,";
            $i++;
        }           
        if($searchParams->french !== NULL)
        {
            $column .= "french,";
            $i++;
        }           
        if($searchParams->school !== NULL)
        {
            $column .= "school,";
            $i++;
        }

        if((trim($searchParams->registrationDate)))
        {
            $column .= "registrationDate";
            $i++;
        }
        if($i > 0)
        {
            // If number of columns is bigger then 0 (if user fill atleast one input)                   
            $columns = explode(",", $column);       
            // Create list of values for query (name of columns and values)
            foreach($columns as $c)
            {                                                   
                if (isset($searchParams->$c)) {     
                    $values .= "'".$searchParams->{$c}."', ";               
                    $col .= $c." = ? AND ";                 
                }                       
            }
            // Remove last "," and space
            $values = substr_replace($values, "", -2);          
            $col = substr_replace($col, "", -5);    
            $query = $col."',".$values;
            $query = "'SELECT * FROM candidates WHERE ".$query;         
            //$query = substr($query, 0, -1); //remove last char ( ' in this case)
            return $query;
        }
        else
        {
            $query = "SELECT * FROM candidates";
            return $query;
        }
    }
4

1 回答 1

0

上面的评论是正确的,你传递一个字符串作为唯一的参数,而不是query期望的多个参数。

一种可能的解决方案是创建一个数组并使用数组项作为参数调用该方法(例如,使用call_user_func_array)。但是,您可以做得更好。

Nette\Database非常强大,它可以为您构建查询。当您将关联数组["column1" => "value1", "column2" => "value2"]作为where方法的唯一参数传递时,它将创建相应的WHERE column1 = 'value1' AND column2 = 'value2'子句。当然,它会安全地转义这些值以防止 SQL 注入。

因此,您可以将代码简化为以下内容:

$columns = ["firstname", "surname", "specialization", "english", "german", "russian", "french", "school", "registrationDate"];
$conditions = [];
foreach ($columns as $c) {
    if (isset($searchParams->$c) && trim($searchParams->$c) !== "") {
        $conditions[$c] = $searchParams->{$c};
    }
}
return $this->db->table('candidates')->where($conditions);

不需要 if–else 语句,因为当数组为空时,NDB 正确地不会附加 WHERE 子句。

于 2015-12-20T03:14:36.143 回答