我是laravel的新手,我试图更新我的导航树。 所以我想在没有foreach的情况下在一个查询中更新我的整个树。
array(
array('id'=>1, 'name'=>'some navigation point', 'parent'='0'),
array('id'=>2, 'name'=>'some navigation point', 'parent'='1'),
array('id'=>3, 'name'=>'some navigation point', 'parent'='1')
);
我只是想问一下 - 在laravel中是否可以插入(如果是数组中的新数据)或更新我在数据库中的当前行?
我想更新所有,因为我在我的树中有字段_lft,_right,parent_id,我使用一些可拖动的js插件来设置我的导航结构 - 现在我想保存它。
我尝试使用
Navigation::updateOrCreate(array(array('id' => '3'), array('id'=>'4')), array(array('name' => 'test11'), array('name' => 'test22')));
但它只适用于单行,而不是像我试图做的那样多行。 也许有另一种方法可以做到这一点?
答案 0 :(得分:6)
我想知道为什么Laravel核心中还没有这种功能(直到今天)。查看this gist查询字符串的结果如下所示:here
我将代码放在这里以防万一以后链接中断,我不是作者:
/**
* Mass (bulk) insert or update on duplicate for Laravel 4/5
*
* insertOrUpdate([
* ['id'=>1,'value'=>10],
* ['id'=>2,'value'=>60]
* ]);
*
*
* @param array $rows
*/
function insertOrUpdate(array $rows){
$table = \DB::getTablePrefix().with(new self)->getTable();
$first = reset($rows);
$columns = implode( ',',
array_map( function( $value ) { return "$value"; } , array_keys($first) )
);
$values = implode( ',', array_map( function( $row ) {
return '('.implode( ',',
array_map( function( $value ) { return '"'.str_replace('"', '""', $value).'"'; } , $row )
).')';
} , $rows )
);
$updates = implode( ',',
array_map( function( $value ) { return "$value = VALUES($value)"; } , array_keys($first) )
);
$sql = "INSERT INTO {$table}({$columns}) VALUES {$values} ON DUPLICATE KEY UPDATE {$updates}";
return \DB::statement( $sql );
}
因此,您可以安全地将数组插入或更新为:
insertOrUpdate(
array(
array('id'=>1, 'name'=>'some navigation point', 'parent'='0'),
array('id'=>2, 'name'=>'some navigation point', 'parent'='1'),
array('id'=>3, 'name'=>'some navigation point', 'parent'='1')
)
);
如果函数中第一行出现任何问题,您只需添加一个表名作为第二个参数,然后注释掉该行,即:
function insertOrUpdate(array $rows, $table){
.....
}
insertOrUpdate(myarrays,'MyTableName');
注意:虽然要小心你的输入,但要小心!并记住没有触及时间戳字段。你可以通过手动添加到主数组中的每个数组来实现。
答案 1 :(得分:5)
现在可以在 Laravel >= 8.x
<块引用>该方法的第一个参数包含要插入或更新的值,而第二个参数列出唯一标识关联表中记录的列。该方法的第三个也是最后一个参数是一个列数组,如果数据库中已存在匹配的记录,则应更新该数组:
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
答案 2 :(得分:2)
口才的风格
public function meta(){ // in parent models.
return $this->hasMany('App\Models\DB_CHILD', 'fk_id','local_fk_id');
}
。 。
$parent= PARENT_DB::findOrFail($id);
$metaData= [];
foreach ($meta['meta'] as $metaKey => $metaValue) {
if ($parent->meta()->where([['meta_key', '=',$metaKey]] )->exists()) {
$parent->meta()->where([['meta_key', '=',$metaKey]])->update(['meta_value' => $metaValue]);
}else{
$metaData[] = [
'FK_ID'=>$fkId,
'meta_key'=>$metaKey,
'meta_value'=> $metaValue
];
}
}
$Member->meta()->insert($metaData);
答案 3 :(得分:0)
不,你不能这样做。您可以一次insert()
多行,并且可以使用相同update()
条件where()
多行,但如果您想使用updateOrCreate()
,则需要使用foreach()
循环。
答案 4 :(得分:0)
在您的控制器中 使用DB; 公共职能arrDta(){
$up_or_create_data=array(
array('id'=>2, 'name'=>'test11'),
array('id'=>4, 'name'=>'test22')
);
var_dump($up_or_create_data);
echo "fjsdhg";
foreach ($up_or_create_data as $key => $value) {
echo "key ".$key;
echo "<br>";
echo " id: ".$up_or_create_data[$key]["id"];
echo "<br>";
echo " Name: ".$up_or_create_data[$key]["name"];
if (Navigation::where('id', '=',$up_or_create_data[$key]["id"])->exists()) {
DB::table('your_table_ name')->where('id',$up_or_create_data[$key]["id"])->update(['name' => $up_or_create_data[$key]["name"]]);
}else{
DB::insert('insert into your_table_name (id, name) values (?, ?)', [$up_or_create_data[$key]["id"], $up_or_create_data[$key]["name"]]);
}
}
答案 5 :(得分:0)
我为所有数据库创建了一个UPSERT软件包:https://github.com/staudenmeir/laravel-upsert
componentWillMount() {
fetch('http://localhost:3000/product/4317892')
.then(res => res.json())
.then(res => {
this.setState({
...this.state, // Not required but just a heads up on using mutation
posts: res
})
})
.catch((error => {
console.error(error);
}));
}
render() {
console.log(this.state)
return (
<div>
<p><strong>Id: {this.state.posts.IDPRODUCT}</strong></p>
<p>Description: {this.state.posts.DESCRIPTION}</p>
</div>
);
}
答案 6 :(得分:0)
我找不到在一个查询中批量插入或更新的方法。但是我只处理了3个查询。我有一个表名shipping_costs。在这里,我想针对运输区域更新运输成本。在此表中,我只有5列ID,area_id,cost,created_at,updated_at。
// first get ids from table
$exist_ids = DB::table('shipping_costs')->pluck('area_id')->toArray();
// get requested ids
$requested_ids = $request->get('area_ids');
// get updatable ids
$updatable_ids = array_values(array_intersect($exist_ids, $requested_ids));
// get insertable ids
$insertable_ids = array_values(array_diff($requested_ids, $exist_ids));
// prepare data for insert
$data = collect();
foreach ($insertable_ids as $id) {
$data->push([
'area_id' => $id,
'cost' => $request->get('cost'),
'created_at' => now(),
'updated_at' => now()
]);
}
DB::table('shipping_costs')->insert($data->toArray());
// prepare for update
DB::table('shipping_costs')
->whereIn('area_id', $updatable_ids)
->update([
'cost' => $request->get('cost'),
'updated_at' => now()
]);