PHP编写 MYSQl INSERT批量入库(新增和更新)
php 编写批量insert批量入库的方法,新增的同时对已经存在的数据进行更新
注:
- 生成的SQL语句中使用了MYSQL中的
ON DUPLICATE KEY UPDATE
- 使用该方法请到数据表中,设置唯一的字段
1. 使用方法
#入库数据必须保持一致,没有的填入空
$data =[
['name'=>'小明','age'=>12,'img'=>'12.png'],
['name'=>'小红','age'=>13,'img'=>'13.png'],
['name'=>'小刚','age'=>11,'img'=>'11.png'],
['name'=>'小黄','age'=>'','img'=>'14.png'],
['name'=>'小黄','age'=>10,'img'=>'10.png'],
['name'=>'小绿','age'=>9,'img'=>''],
];
#把多条数据入库studnet表(studnet表中作者设置了name字段唯一)
mostInsert('studnet',$data,'',true);
2. mostInsert()详细代码
/**
* 批量数据入库
* @param $data_arr array [必须] 需要入库的数据
* @param $table string [必须] 表名
* @param $fields string [非必须] 需要入库的字段 不填默认是$data_arr中的k值
* @param $update bool|string [非必须] 入库时出现重复需要更新的字段 true:使用$fields的字符串
* @throws ErrorException
* @example
* 简单使用:
* 1. 仅新增 saveData($table,$data_arr)
* 2. 批量新增兼更新 saveData($table,$data_arr,'',true)
* 方法原理:
* MYSQL语法: Insert into…ON DUPLICATE KEY UPDATE…
* 备注:
* 1. 该方法会根据表中的唯一字段,判断新增还是更新(表中未设置唯一字段,则根据主键id 来判断)
* 2. 当该方法来批量新增同时批量更新时,请一定要保证入库的数据包含【唯一字段的数据】或者【主键id】
* 3. 缺点: 使用该方法,需要在表中建立唯一索引
*/
function saveData(string $table,array $data_arr,string $fields='',$update=false)
{
$i = 0;
$left ='(';
$right='),';
// 批量入库时更新的内容
$update_sql = '';
if(count($data_arr)>50000){
throw new ErrorException('CrudFun/mostInsert:入库的数据太多了超5w了...');
}
if(empty($fields)) {
if(!isset($data_arr[0])){
throw new ErrorException('CrudFun/mostInsert:传入数据格式不对、或者为空...');
}
foreach ($data_arr[0] as $key=>$value){
$fields .= "`$key`,";
}
$fields = rtrim($fields,',');
}
$fields_arr = explode(',',$fields);
// 判断是否需要更新
if($update===true){
$update_sql = $this->insertAndUpdateSql($fields);
}
if(is_string($update)){
$update_sql= $this->insertAndUpdateSql($update);
}
$sql = "INSERT INTO $table ($fields) VALUES ";
foreach ($data_arr as $key => $data)
{
$now_sql = '';
foreach ($fields_arr as $field){
$now_field = trim($field,'`');
if(!array_key_exists($now_field,$data)){
throw new ErrorException("CrudFun/mostInsert:data[$key][$now_field]字段不存在...");
}
$now_sql.="'{$data[trim($field,'`')]}',";
}
$sql .= $left.rtrim($now_sql,',').$right;
if($i>=5000){
// 请更换自己 执行原生SQL的方法
$this->db->query(rtrim($sql,',').$update_sql);
$i=0;
}
$i++;
}
return $this->db->query(rtrim($sql,',').$update_sql);
}
/**
* 生成 入库时同时判断更新的mysql代码
* @param $fields_arr_str string/array ='name,sex';
* @return string sql
*/
function insertAndUpdateSql($fields_arr_str)
{
if(is_array($fields_arr_str)||is_string($fields_arr_str)){
$sql = " ON DUPLICATE KEY UPDATE ";
$fields = $fields_arr_str;
is_string($fields_arr_str) && $fields=explode(',',$fields_arr_str);
foreach ($fields as $fd){
$sql .= " $fd = VALUES($fd),";
}
return trim($sql,',');
}
return '参数类型只能是一维数组或字符串!';
}