php mysql 拼接批量更新、插入SQL (已封装好,直接调用!)
批量插入
功能:
1.返回批量插入sql语句
2.拼接时自动识别字符串或数字,判断是否加 ' '
3.ON DUPLICATE KEY UPDATE 可以选择 存在则插入,不存在则更新
4.REPLACE INTO语句,删除再插入数据
/** * 返回批量插入sql语句 * @param $table * @param array $data 二维数组 * @param string $updateSql 更新内容,存在唯一索引(主键、唯一约束)值,则更新这条数据 eg: on duplicate key update time = unix_timestamp(now()) , type = 4 */ function insertAllSql($table,$data,$updateSql='') { $start = "insert into {$table}"; // 字段 $field = ''; foreach ($data[0] as $k => $v){ $field .= "`$k`,"; } $field = '('.rtrim($field,',').') values'; // 判断字段是否为字符串类型 $res = ComLib::select("SELECT COLUMN_NAME as 'field' ,DATA_TYPE as 'type' FROM information_schema.`COLUMNS` where TABLE_NAME = '{$table}' "); foreach ($res as $v){ if ($v['type'] == 'varchar') $fieldArr[$v['field']] = 1; } // 赋值 $after = ''; foreach ($data as $arr){ $tmp = ''; foreach ($arr as $k => $v){ if (isset($fieldArr[$k])){ $tmp .= "'{$v}',"; }else{ $tmp .= $v.','; } } $after .= '('.rtrim($tmp,',').'),'; } $after = rtrim($after,',').' '; $sql = $start.$field.$after.$updateSql; // var_dump($sql); return $sql; }
使用例子:
// 实现效果: // 插入前两条数据;更新 id=3那条数据,更新 time = 当前时间 , 更新 status = 1 $data = [ ['name' => 'aa','age'=>15], ['name' => 'bb','age'=>18], ['name' => 'cc','age' => 18,'id' => 3], ]; $updateSql = ' on duplicate key update `time` = unix_timestamp(now()) , `status` = 1 '; $sql = insertAllSql('admin_user',$data,$updateSql); Db::execute($sql);
批量更新
功能:
1.可指定唯一索引
2.可添加额外更新条件
/** * 批量更新函数,返回批量更新执行的sql * @param string $table 要更新的表名,例:goods表 * @param array $data 待更新的数据,二维数组格式,例:$data = [['id' => 1, 'name' => 'zhangsan'],['id' => 2, 'name' => 'lisi']]; * @param string $field string 值不同的条件,例:id * @param array $params where条件的其他额外判断条件,键值对应的一维数组,例:['parent_id' => 1] * @return bool|string */ function batchUpdate($table = '', $data = [], $field = '', $params = []) { if (!is_array($data) || !$field || !is_array($params)) { return false; } $updates = parseUpdate($data, $field); $where = parseParams($params); // 获取所有键名为$field列的值,值两边加上单引号,保存在$fields数组中 $fields = array_column($data, $field); $fields = implode(',', array_map(function($value) { return "'".$value."'"; }, $fields)); $sql = sprintf("UPDATE `%s` SET %s WHERE `%s` IN (%s) %s", $table, $updates, $field, $fields, $where); return $sql; } /** * 将二维数组转换成CASE WHEN THEN的批量更新条件 * @param $data array 二维数组 * @param $field string 列名 * @return string sql语句 */ function parseUpdate($data, $field) { $sql = ''; $keys = array_keys(current($data)); foreach ($keys as $column) { if ($column == $field) { continue; } $sql .= sprintf("`%s` = CASE `%s` \n", $column, $field); foreach ($data as $line) { $sql .= sprintf("WHEN '%s' THEN '%s' \n", $line[$field], $line[$column]); } $sql .= "END,"; } return rtrim($sql, ','); } /** * 解析where条件 * @param $params * @return array|string */ function parseParams($params = []) { $where = []; if (!empty($params)) { foreach ($params as $key => $value) { $where[] = sprintf("`%s` = '%s'", $key, $value); } } return !empty($where) ? ' AND ' . implode(' AND ', $where) : ''; }
使用列子:
// 实现效果: // 更新id=1、2、3且status = 1 的数据。 $data = [ ['name' => 'aa','age'=>15,'id' => 1], ['name' => 'bb','age'=>18,'id' => 2], ['name' => 'cc','age' => 18,'id' => 3], ]; $sql = batchUpdate('admin_user',$data,'id',['status'=>1]); Db::execute($sql);