【问题标题】:PDO fetch data where id's not equal to arrayPDO 获取 id 不等于数组的数据
【发布时间】:2014-04-02 20:36:40
【问题描述】:

所以我正在将我的项目从基于 XML 的模式更新为 mysql 数据库模式。我正在尝试弄清楚如何执行此功能-如果可能的话。我想从数据库中获取一些值不等于数组中值的行。

function catchUpgrades($id)
{
    $sql = "SELECT id, name, cost FROM upgrades WHERE prereq <> :id OR null <> :id";
    $que = $this->db->prepare($sql);
    $que->bindParam('id', $id[0]);
    try { 
        $que->execute();
        while($row = $que->fetch(PDO::FETCH_BOTH))
        {
            $array['name'] = $row[1];
            $array['id'] = $row[0];
            $array['cost'] = $row[2];
        }
    }catch(PDOException $e) {}
}
function showUpgrades()
{
    $html = "<div id='upgrades'>";
    $array = $this->getUserUpgrades();
    $upgrades = $this->catchUpgrades($array);
    print_r($upgrades);


}

【问题讨论】:

  • 不是答案,但您不能在准备好的语句中使用同名的命名参数标记两次 (php.net/manual/en/pdo.prepare.php) -> prereq &lt;&gt; :id OR null &lt;&gt; :id
  • 在那句话中,你是说 prereq 不等于 ID,或者 ID 不为空?该语句使您看起来好像有一个名为 null 的数据库列,这将是一个问题。
  • @Sean:PDO 文档说得很清楚,不能两次使用相同的命名参数;当我们很久以前遇到那个“错误”时,我不记得文档中提到过这个限制。
  • @Sean,这可能是问题的一部分;它应该是“nullIf”......现在将其修复到其他答案!

标签: php mysql sql pdo


【解决方案1】:

您可以绑定数组中的值。此函数将在稍作更改时工作 - 我添加了一个冒号、第二个绑定参数(具有不同的占位符名称以避免 PDO 冲突)和一个返回值。显然otherColumnName 将不得不改变。如果这不是您想要的,请告诉我。我留下了评论...

function catchUpgrades($id)
{
    $sql = "SELECT id, name, cost FROM upgrades WHERE prereq <> :id OR otherColumnName <> :id2";
    $que = $this->db->prepare($sql);
    $que->bindParam(':id', $id[0]); //note the : before id
    $que->bindParam(':id2', $id[0]); //note the : before id2
    try { 
        $que->execute();
        while($row = $que->fetch(PDO::FETCH_BOTH))
        {
            $array['id'] = $row[0];                
            $array['name'] = $row[1];
            $array['cost'] = $row[2];
        }
        return $array;
    } catch(PDOException $e) {}
}

然后,要调用该函数,您将有如下一行:

$results_array = catchUpgrades($id);

【讨论】:

  • +1 指出bindParam 方法的第一个参数中缺少':' 字符,并指出在语句中仅引用一次绑定参数名称的PDO 限制。
  • @spencer7593 谢谢。骑士精神没有死!
  • 所以你需要在绑定之前有 : 吗?我从来没有遇到过这方面的问题,并且一直在做这件事:迄今为止我所有的参数。
  • 根据the documentation for bindParam,您确实需要它。没有它,结果可能无法预测。
  • 我正在尝试这个,由于某种原因它返回一个空数组。 (或者数组没有粘住......两者之一......)
【解决方案2】:

这个谓词永远不会返回 TRUE:

OR null <> :id

NULL 是表示特殊“null”值的关键字。与 NULL 的不等比较永远不会返回 TRUE。

要测试:id 是否包含非NULL 值,请使用ANSI 标准"IS NOT NULL" 运算符,如下所示:

OR :id IS NOT NULL

作为非标准的替代方案,您可以使用 SQL 特定的“空安全比较器”运算符,如下所示:

OR NOT (:id <=> NULL)

但是,你想做那个测试是没有意义的,因为它与前面的谓词是多余的。

当为:id 提供的值为 NULL 时,您想要什么行为?你想匹配每一行吗? (您的查询看起来与我们用于搜索条件的模式很相似,其中为绑定参数提供 NULL 值会禁用搜索条件,如下所示:

WHERE ( prereq <> :id OR :id IS NULL )

如果为:id 提供的值是空值,则第二部分将返回 TRUE,而第一个条件的计算结果根本无关紧要。对于:id 的非 NULL 值,第二个条件将为 FALSE,因此第一个条件需要为 TRUE 才能返回一行。

(但这只是一个猜测,不清楚你想在那里做什么。)


另外,当我们在一个语句中多次使用同一个命名参数时,我们遇到了 PDO 问题。 (当我们遇到问题时,PDO 文档并没有指出这有问题。)我们使用的解决方法是在语句中只引用一次命名参数,通过使所有命名参数唯一。

解决方法是这样做:

$sql = "SELECT id, name, cost FROM upgrades WHERE prereq <> :id1 OR :id2 IS NULL";
$que = $this->db->prepare($sql);
$que->bindParam(':id1', $id[0]);
$que->bindParam(':id2', $id[0]);

(我不确定这是否在 PDO 的后续版本中得到修复;它可能不再是需要像这样的解决方法的问题。)

(我不确定这是否能回答你的问题,但我试了一下。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2014-02-19
    • 1970-01-01
    相关资源
    最近更新 更多