【问题标题】:Prepared Statements and updating multiple rows准备好的语句和更新多行
【发布时间】:2014-09-10 17:50:36
【问题描述】:

我对准备好的语句相当陌生,并且正在过渡项目...

我必须转换的最后一块是我必须更新多行/记录的一块。

这似乎对我有用...但是,我很好奇并想知道我的技术,并且还发回某种响应(布尔值或其他),表明一切都是成功或失败的。想法?评论?有什么建议吗?

function timeUpdate($uID, $galArr, $timeStamp) {
    global $mysqli; //my connection is set elsewhere (bad/good?)
    $q = "UPDATE someTable SET timeStamp = ? WHERE galleryID = ? AND uniID = ?";
    $stmt = $mysqli->prepare($q);
    $stmt->bind_param("iii", $timeStamp, $gID, $uID);

    foreach($galArr as $value) {
        $gID = $value[0];
        if(!$stmt->execute()) {
             throw new Exception($stmt->error, $stmt->errno);
        }
    }
    $stmt->close();
}

提前致谢。任何链接,建议都非常感谢。

【问题讨论】:

  • 我认为您应该询问如何将 IN() 与准备好的语句一起使用,因为将 IN() 用于 galleryID 会比 foreach 循环更有效。
  • @developerwjk,很酷。我会看看我能找到和阅读的内容。

标签: php mysqli


【解决方案1】:
  1. 始终建议您将连接作为函数参数传递,而不是使用global。如果您愿意,可以研究其中的原因,或者相信我的建议 - 会有一些 StackOverflow 页面专门讨论这个问题。

  2. 在绝大多数情况下,函数应该return 一些东西。就您而言,我认为返回一系列成功/失败结果是有意义的;或者如果您有其他特定需求,您可以退回任何您喜欢的东西。

  3. 您使用准备好的语句和绑定参数是明智/正确的。我只想解释一下,如果你只是写foreach(array_column($galArr) as $gID){,它就不需要$gID = $value[0];。该声明足以将变量提供给execute()。也就是说,如果您可以准备并将第一列数据从 $galArr 传递给您的自定义函数,那么您的函数中的代码将更加简洁...... (foreach($gIDs as $gID){)。

  4. 最不重要的:我不喜欢声明一次性变量。根据这个原则,我不会声明$q,而是选择简单地将字符串写入prepare()。 (这没什么大不了的——如果你愿意,你可以忽略这个建议)


用于改进结果跟踪的个性化查询:

function timeUpdate($mysqli, $uID, $galArr, $timeStamp) {
    if(!$stmt=$mysqli->prepare('UPDATE someTable SET timeStamp = ? WHERE galleryID = ? AND uniID = ?')){
        return $result[]=['syntax'=>'fail','outcome'=>'Prepare Error: '.$mysqli->error];
    }elseif(!$stmt->bind_param("iii", $timeStamp, $gID, $uID)){
        $result[]=['syntax'=>'fail','outcome'=>'Bind Error: '.$stmt->error];
    }else{
        foreach(array_column($galArr,0) as $gID) {  // if these values are not unique, misinformation will be possible because I am using $gID as $result keys
            if(!$stmt->execute()) {
                $result[$gID]=['syntax'=>'fail','outcome'=>'Error: '.$stmt->error];
            }else{
                $result[$gID]=['syntax'=>'pass','outcome'=>'Affected Rows: '.$stmt->num_rows()];
            }
        }
    }
    $stmt->close();
    return $result;
}

最佳实践要求您对给定任务进行尽可能少的查询。您的任务可以使用WHERE / IN 子句组合成一个UPDATE 查询。不幸的是,mysqli 的预处理语句在处理可变数量的占位符时需要一个复杂的过程。 See this post 可能会是什么样子。 (PDO 能够更好地处理可变数据。)所以基本上,我是说如果你想对数据库进行一次调用,那就需要权衡取舍——你必须写更多的东西(更难阅读)代码,您将无法控制返回的通过/失败消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多