thinkPHP6 批量更新数据

thinkPHP6升级以后,核心框架改版了很多语法内容,尤其是6.0.3+之后,不允许在模型里直接调用query和execute执行原生SQL方法(注:6.0.8这个版本有一个重大的bug,在这个版本里,不能使用query和execute执行原生SQL方法,不论你是否在model还是直接调用实例Db类,都不行,所以建议后面项目升级版本,跳过6.0.8这个版本,当时把我整的差点怀疑人生,不能执行原生SQL,简直反人类,不过幸好在6.0.9之后修复了这个问题),扯远了,咋们言归正传,thinkPHP对批量执行更新,框架里是没有这个操作的,只能直接封装,代码如下:

批量更新示例代码如下

示例代码 PHP封装函数

/**
 * 执行原生SQL查询
 * @param string $sql SQL语句
 * @return mixed
 */
function db_query(string $sql)
{
    $db_prefix = db_prefix();
    // 替换表前缀
    $sql = str_replace("__PREFIX__",$db_prefix,$sql);
    return Db::query($sql);
}

/**
 * 执行原生SQL
 * @param string $sql SQL语句
 * @return mixed
 */
function db_execute(string $sql)
{
    $db_prefix = db_prefix();
    // 替换表前缀
    $sql = str_replace("__PREFIX__",$db_prefix,$sql);
    return Db::execute($sql);
}

/**
 * 获取表前缀
 * @return mixed
 */
function db_prefix(){
    return facade\Env::get("database.prefix");
}

/**
 * 批量更新数据
 * @param string $table_name 表名
 * @param array $data 更新的数据
 * @param string $field 作为更新条件的字段,注:主键pk
 * @return mixed
 */
function db_batch_update(string $table_name,array $data,string $field)
{
    // 生成SQL
    $sql = 'UPDATE __PREFIX__'.$table_name." SET ";
    $fields = $casesSql = [];
    foreach ($data as $key => $value) {
        // 指定更新字段不存在
        if (!isset($value[$field])){
            continue;
        }
        // 记录更新字段
        $temp = $value[$field];
        if(!in_array($temp,$fields)){
            $fields[]=$temp;
        }
        // 拼接更新字段条件
        foreach ($value as $k => $v) {
            // 更新条件字段不更新
            if ($k == $field){
                continue;
            }
            $temp = $value[$field];
            // 拼接CASE,默认CASE头
            $caseWhen = isset($casesSql[$k]) ? $casesSql[$k] : "`{$k}` = (CASE `{$field}` ";
            // 拼接WHEN
            $caseSql = sprintf(
                "%s WHEN '%s' THEN '%s' ",
                $caseWhen,$temp,$v
            );
            $casesSql[$k] = $caseSql;
        }
    }
    if (!$casesSql){
        return false;
    }
    $endSql = [];
    // 拼接结束END
    foreach ($casesSql as $key=>$val){
        $endSql[] = $val." END)";
    }
    $sql .= implode(',',$endSql);
    unset($data,$casesSql,$endSql);
    // 拼接WHERE
    $str = implode(',', array_map('change_to_quotes', $fields ));
    $sql .=" WHERE `{$field}` IN ({$str})";
    // 创建并执行完整SQL
    $res = db_execute($sql);
    return $res;
}

/**
 * 字符串加上单引号
 * @param $str
 * @return string
 */
function change_to_quotes($str) {
    return sprintf("'%s'", $str);
}

注:本示例代码,是是基于PHP8开发的,低版本的项目,请适当修改入参,可以根据自己的业务需求对代码进行进一步优化,其他框架也可以使用,只需要修改一下执行SQL即可。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐