使用 LIKE 语句查询不准确

Innacurate query with LIKE statement

语言是PHP,数据库ORM是RedBean

if(isset($get['last']) || isset($get['first'])){        
    $query = '';
    $search_params = [];
    if(isset($get['first']) && !isset($get['last'])){
        //search only with first name
        $query .= ' AND name LIKE :first ';
        $search_params[':first'] = '%'.$get['first'].'%';
        $args['first'] = $get['first'];
    }
    else if(!isset($get['first']) && isset($get['last'])){
        //search only with last name
        $query .= ' AND name LIKE :last ';
        $search_params[':last'] = '%'.$get['last'].'%';
        $args['last'] = $get['last'];
    }
    else{
        //search with both first and last name
        $query = ' AND (name LIKE :first OR name LIKE :last) ';
        $search_params[':first'] = '%'.$get['first'].'%';
        $search_params[':last']  = '%'.$get['last'].'%';
        $args['first'] = $get['first'];
        $args['last'] = $get['last'];
    }   
    if($args['admin']){
        //if the user is the admin of the account they can see all transactions
        $args['transaction'] = admin_example($id, $query, $search_params);
    }else{
        //if the user is a member of the account and was involved in the transaction 
        $args['transaction'] = member_example($id,$user->email,$query,$search_params);
    }
}else{
    $args['transaction'] = false;
}

//get archived transaction the user was involved in matching search parameters
function admin_example($account_id,$query_segment,$search_params)
{
    $params = array_merge([':id'=>$account_id],$search_params);
    return R::getAll('SELECT name,tx_id,otp,property_type,property,ins_documents,active FROM transaction WHERE account_id=:id AND active="0" '.$query_segment.' ORDER BY name ASC',
        $params
    );
}

//get archived transaction the user was involved in for the current account and matching search parameters
function member_example($account_id,$email,$query_segment,$search_params)
{
    //gets transactions the account member is able to view.
    $params = array_merge([':account'=>$account_id,':email'=>$email],$search_params);
    return R::getAll('SELECT name,tx_id,otp,property,property_type,ins_documents,active FROM 
    transaction WHERE account_id=:account AND (primary_email=:email OR secondary_email=:email) AND active="0" '.$query_segment.' ORDER BY name ASC',
        $params
    );
}

查询

SELECT 
    name,tx_id,otp,property_type,property,ins_documents,active 
FROM 
    transaction 
WHERE 
    account_id='1' AND active='0' AND (name LIKE '%ABC%' OR name LIKE '%DEF%') 
ORDER BY 
    name ASC

假设如下:

  1. 我在名字输入中输入 "ABC",在姓氏输入中输入 "DEF"。
  2. table 有 1 行满足 active="0" 条件。
  3. 该行的名称列包含姓氏和名字,以逗号分隔,即 Flip, Tre.

似乎无论在输入框中输入什么,记录总是被检索,当它不应该匹配任何一个 LIKE statement.s 我不知道为什么,我是想知道还有什么我可以做的吗?我已经在 name 列中添加了一个索引,但没有骰子。我也尝试使用 REGEXP 但是我无法检索到类似的东西。

根据您的代码和显示问题的评论,看起来当 lastfirst 在表单上为空时,它们仍在传递给脚本。

这意味着isset()检查通过了,但是它们没有值(即空字符串,即'')。当这被添加到您的 or 子句时,它会添加 '%%',这显然会匹配任何值。

在将这些变量包含在查询中之前,您还需要检查并确保这些变量未设置为空字符串。您可以通过在变量上调用 isempty() 或检查它是否与空字符串 ''.

不等来做到这一点