php SQL WHERE(列1 =全部或列1 =“列1”)AND列2 =“列2”

muk1a3rh  于 2022-12-25  发布在  PHP
关注(0)|答案(2)|浏览(210)

我正在使用选择框构建搜索页(这里我至少有15个这样的选择框)就像我在这个问题中提到的,通过GET方法将选项值从一个页面传递到另一个页面。但是我很笨,没有考虑到WHERE子句不接受 * forall的情况(everywhere)和我给予SELECTED选项的任何值,这将在**WHERE condition中转换为COLUMN = 'VALUE',因此,查询将在我的数据库中搜索 * 的值,all、&或我将给予并返回的任何其他值:未找到记录
我发现了一些相关的职位就像这个问题:建议使用SQL WHERE column = everythingWhy would someone use WHERE 1=1 AND in a SQL clause?,其中WHERE column=column(1=1),但正如第一个链接所述,这不是一个有效的解决方案。
一个建议的工作解决方案是使用
IF
case,但是如果我想到我的15个框和它的所有类型的组合,(当用''/any/all值选择一些框和取消选择一些框时,我立刻感到头痛。
因此,我考虑询问是否可以在实际查询之外构建这个
WHERE条件**,然后将其应用于查询内部。
作为一个程序员,我可能会说一些愚蠢的话,但也许你可以帮助我解决它。我想从第二页的GET开始,使用我的构建作为例子,所以,在第二页我开始:

$mushtype = $_GET ['mushtype'];
  IF (isset($mushtype) { 
    $var1 = echo "mushtype = '$mushtype'"; 
  } ELSE { 
    ignore $var1;
  }

// similar for the next 14 columns
//when I have all these, build a query

$stmt = $conn->prepare("SELECT * FROM Mydatabase WHERE $var1 AND $var 2 ... AND $var15 ;

你认为,做这样的事情是可能的,如果可能,怎么做?
编辑. @Flewz我的过滤器看起来像:x1c 0d1x并通过GET得到如下结果:

]

我的数据库如下所示:

我的where子句是

$stmt = $conn->prepare("SELECT * FROM Mydatabase WHERE mushtype='$mushtype'AND capsurface='$capsurface' AND capform='$capform')

我没有在这里重复所有15个过滤器,这在时间上可能会更多,但你得到的想法。
所以,用户不需要使用所有的过滤器来识别它的蘑菇,它只会使用需要的一个,但在我的句子中,如果一列没有使用,返回给我一个没有找到记录消息,我想避免这种情况。我愿意接受任何建议。

tmb3ates

tmb3ates1#

WHERE子句是用来过滤数据的,所以如果你不需要过滤(想查看所有记录),完全跳过WHERE子句就行了,它是不需要的。

yzuktlbb

yzuktlbb2#

既然你已经更新了你的问题,让我们从一些安全的做法开始。
您使用的是准备好的语句,这很好,只是您用了错误的方法。
因为你使用的是php,我们有一个命名参数选项,见下面的例子。

$sql = 'SELECT name FROM pets WHERE species=:species;';
$stmt = $con->prepare($sql);
$stmt->execute([ 'species' => 'cat' ]);
$err = $stmt->errorInfo();

if($err[0] != '00000'){
    // handle error, code is in $err[2]
}

while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    // do something
}

WHERE species=:species:species是我们在prepared语句中的变量,我们通过传递一个带键的数组给execute方法来填充它,这是唯一安全的方法。
对于你手头的问题,最容易理解的是大量的if语句。可以用配置对象和for循环来完成。
未经测试,可能行不通。

// we need to figure out which GET parameters came trough
$all_get_keys = [ 'mushtype' ];
// we will use this to make our sql statement
$get_key_config = [
    'mushtype'      => [
        'db_col'    => 'mtype',
        'assoc_var' => 'mtype'
    ]
];
// for parsed $_GET
$get_params = [];

// go over all possible keys
foreach($all_get_keys as $key){
    // if we have it, push to array
    if(isset($_GET[$key])){
        $get_params[] = [
            'key'   => $key,
            'value' => $_GET[$key]
        ];
    }
}

// how many we got
$get_var_size = count($get_params);

if($get_var_size == 0){
    // no point in doing anything
    // echo error message
    echo 'I am a teapot';
    exit();
}

$stmt_data = [];
$sql = 'SELECT * FROM some_table';

// in addition we can check if we have all get params and adjust query
if($get_var_size == count($all_get_keys)){
    // execute
}else{
    $sql .= ' WHERE ';

    for($i = 0; $i < $get_var_size; $i++){
        // get config for our get key
        $cfg = $get_key_config[$get_params[$i]['key']];

        // append to sql query
        $sql .= $cfg['db_col'] . '=:' . $cfg['assoc_var'];
        // don't forget on variable
        $stmt_data[$cfg['assoc_var']] = $get_params[$i]['value'];

        // don't add AND if its our last
        if($i < $get_var_size - 1){
            $sql .= ' AND ';
        }
    }

    //execute
}

// check for error
// do data operation

if和for循环之间的唯一区别是config中的选项将被类型化为if语句。

相关问题