【问题标题】:Null or Not Null value in mysql where conditionmysql where条件中的Null或Not Null值
【发布时间】:2015-08-08 00:57:14
【问题描述】:

我正在用 php 代码编写小型 mysql 选择查询,在选择查询中它具有三个不同的 where 条件,例如

SELECT * FROM table1 WHERE pid = $pid AND qid = $qid AND text="$text" ; 

它会动态改变变量,有时其中一个变量会变为空,那时我的情况看起来像

SELECT * FROM table1 WHERE pid = $pid AND text="$text" ;

同样的事情也可以用于文本和 pid,我该怎么做,有什么解决方案或者我应该去 php 中的 if/switch 条件..

【问题讨论】:

  • 在 php 中使用 if/switch
  • 查看@GordonLinoff 的回答,注意您的代码对 SQL 注入是开放的,请查看准备好的语句。
  • 这是个坏主意,因为如果您的所有参数都为空,您将收到糟糕的查询,该查询将选择所有记录...

标签: php mysql sql pdo


【解决方案1】:

您可以使用ifs 创建查询并执行 PDO 准备语句 (http://php.net/manual/en/pdo.prepare.php)。

<?php
$query = "SELECT * FROM table1 WHERE 1 = 1";
$params = array();

if(null !== $pid) {
    $query .= ' AND pid = :pid';
    $params[':pid'] = $pid;
}
if(null !== $qid ) {
    $query .= ' AND qid = :qid';
    $params[':qid'] = $qid;
}
if(null !== $text) {
    $query .= ' AND text = :text';
    $params[':text'] = $text;
}

$sth = $dbh->prepare($query);
$sth->execute($params);
$result = $sth->fetchAll();

【讨论】:

  • 谢谢,它帮助了我..:)
  • @prabhu,很高兴听到这个消息。
  • 您的编辑使这个答案毫无用处......相反,您可以删除您的答案并为另一个答案投票。
【解决方案2】:

这里是另一个 mysql 变体:

SELECT *
FROM tbl
WHERE
    IF($pid > 0, pid = $pid, 1 = 1)
AND IF($qid > 0, qid = $qid, 1 = 1)
AND IF($text > '', `text` = $text, 1 = 1)
;

但这里是硬编码的值。并且您不能选择 pid 或 qid 正好等于 0 或 text 等于 ''(空字符串)的行。
而且您可以接收到将选择表中所有行的查询,我想这会很糟糕...

PHP:

<?php

$dbh = new PDO('mysql:dbname=test;host=127.0.0.1', 'root');
$pid = 1;
$qid = 2;
$text = '3';
$sql = 'SELECT * FROM tbl WHERE 1 = 1';
$params = [];
if (isset($pid)) {
    $sql .= ' AND pid = :pid';
    $params[':pid'] = $pid;
}
if (isset($qid)) {
    $sql .= ' AND qid = :qid';
    $params[':qid'] = $qid;
}
if (isset($text)) {
    $sql .= ' AND `text` = :text';
    $params[':text'] = $text;
}
$sth = $dbh->prepare($sql);
$sth->execute($params);
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
var_export($result);

【讨论】:

  • 第二个版本比第一个版本大大好,而第一件事我什至不知道为什么会出现。这很奇怪而且很浪费。不必要的条件不属于查询字符串,忽略它们是应用程序代码的工作,而不是 MySQL 忽略它们。第二个版本可以通过创建$conditions = [] 来清理,然后附加到该数组,稍后将其引入到带有implode(' AND ', $conditions) 的查询中,以使其更加动态并删除无意义的1=1 东西。
【解决方案3】:

您可以将其包含在 SQL 中,如下所示:

SELECT * 
FROM table1 
WHERE ("$pid" = "" OR pid = "$pid") 
AND ("$qid" = "" OR qid = "$qid") 
AND ("$text" = "" OR text="$text") ;

MySql-Server 将看到... WHERE ("" = "" OR pid = "") 并在执行前通过删除这部分优化查询。

【讨论】:

  • 。这只会使已经猖獗的注入问题翻倍。
  • 嗯,是的,我同意,必须处理 SQL 注入。但是,这超出了这个问题的范围。例如,$pid 可能已被预先转换为 (int),而 $text 可能是静态字符串。
  • 正是这些假设一切都好导致了严重的问题。编写正确的代码永远不会超出范围。 == 也不是有效的 MySQL 比较。
猜你喜欢
  • 2013-07-07
  • 2010-10-23
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2014-12-08
  • 2013-04-18
相关资源
最近更新 更多