I am inserting multiple rows at the same time, say 2 rows
$multiple_rows = [
['email' => 'taylor#example.com', 'votes' => 0],
['email' => 'dayle#example.com', 'votes' => 0]
];
DB::table('users')->insert($multiple_rows);
How can I get those inserted ids.
I am doing it, this way for now.
foreach($multiple_rows as $row){
DB::table('users')->insert($row);
$record_ids[] = DB::getPdo()->lastInsertId();
}
Any other good way to do it, without inserting single row each time.
You could do something like the following:
$latestUser = DB::table('users')->select('id')->orderBy('id', 'DESC')->first();
$multiple_rows = [
['email' => 'taylor#example.com', 'votes' => 0],
['email' => 'dayle#example.com', 'votes' => 0]
];
DB::table('users')->insert($multiple_rows);
$users = DB::table('users')->select('id')->where('id', '>', $latestUser->id)->get();
If you really need all the inserted ID's
$dataArray = [
['name' => 'ABC'],
['name' => 'DEF']
];
$ids = [];
foreach($dataArray as $data)
{
$ids[] = DB::table('posts')->insertGetId($data);
}
To get all id with a massive insertion I think the good way is to first get the last id in the table, make the massive insertion and get the last id. In theory they must follow, unless there has been an insertion from another connection. To avoid that the solution is a transaction.
Update
Also read the documentation
Related
Solution
foreach($request->all() as $record){
EventViews::query()->updateOrCreate(['id'=>$record['id']], $record);
}
Question
How do I update a whole table by passing a request array? It should update existing rows and create new ones if id doesn't exist. If possible without having to loop over the whole table.
Attempts that don't work:
EventViews::query()->updateOrCreate($request->all());
.
DB::transaction(function ($request) {
foreach ($request->all() as $record) {
EventViews::updateOrCreate($record);
}
});
.
$model = new EventViews($request->all());
$model->fill($request->all())->save();
assuming your request payload looks something like
records[]=[id=1,name=foo,description=foo,c=1]&
records[]=[id=2,name=bar,description=bar,c=1]&
...
you could loop over it like:
$input = $request->input('records');
foreach($input as $record){
EventViews::query()->updateOrCreate(['id'=>$record['id']],$record);
}
if your request looks like:
1=[name=foo,description=foo,c=1]&
2=[name=bar,description=bar,c=1]&
...
where the parameter name is the id, then you could use:
$input = $request->input();
foreach($input as $key => $record){
EventViews::query()->updateOrCreate(['id'=>$key],$record);
}
updateOrCreate receives 2 parameters, the first is the constrains and the second is the data.
I don't know your request structure, but it's good practice verify it before throwing it into your database.
Example:
Model::query()->updateOrCreate(
['my_column' => $request->input('my_column')],
[*array of column/values of what should be updated*]
)]
If exists a Model with given my_column value, it will update it's value with the associative array passed on the second argument, otherwise it will create a new entry.
you can use this method :
$flight = Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
or
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
for get more information see this link:
https://laravel.com/docs/9.x/eloquent#upserts
Is there something like UpdateOrCreate I can use to have different values on create and on update. Meaning if it’s updating i don’t want it to change a certain column but i want it to insert the first time.
eg
$person = ['name'=> 'John', 'age' => 6, 'joined' => '2017-01-01'];
If John exists update age. If it doesn’t insert age and joined;
People::updateOrCreate(
['name' => $person['name']],
['age' => $person['age'], 'joined' => $person['joined']]
)
will update joined every time and i don't wanna change it.
You can use updateOrNew which doesn't persist it to the database and then check if it is not already in the database you can change the property you want to change.
$record = People::updateOrNew(
['name' => $person['name']],
['age' => $person['age']]
);
if(!$record->exists()) {
$record->joined = $person['joined'];
}
$record->save();
But if you are only trying to get the record if it exists and create it if it doesn't, use firstOrCreate() instead. That won't affect existing records, only return them, and it will create the record if it doesn't exist.
There is no any other option else you can try following:
$person = People::where('name', $name)->first();
if (!is_null($person)) {
$person->update([
'age' => $age
]);
}else{
$person = People::create([
'name' => $name,
'age' => $age,
'joined' => date('Y-m-d')
]);
}
Method 1 : Here I wrote the code for insert booking seat data into the database
Problem : When I book new seat it will creating new row so I'm getting duplicate rows so I tried method 2
Method 1 code :
$booking = new Bookings();
$booking->users_id = 4;
$booking->schedules_id = $schedules_id;
$booking->buses_id = $buses_id;
$booking->routes_id = $routes_id;
$booking->seat = implode(',', $seat);
$booking->price = $request->price;
$booking->profile = 'pending';
Method 2 : Here checking schedules_id equal to exists schedules_id then update seat and other data's
Problem : Insert new data updating old data
Method 2 code :
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id], // match the row based on this array
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => json_encode($seat),
'price' => $request->price,
'profile' => 'pending',
]
);
// I don't know this is logically correct or wrong
My idea : Here I'm retrieving old data and storing into one variable then merging old data and new data into one column
Problem : Getting error.
My idea code :
$extSeat = DB::table('bookings')->select('seat')->get();
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id],
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => implode(",", array_merge($seat,$extSeat)),
'price' => $request->price,
'profile' => 'pending',
]);
what i actually need ? : i need merge exists data with new data without updating.
Old data look like A1,B1
when insert new data like C1
i need data like this A1,B1,C1
I hope I explain clear enough. Any help is appreciated, thank you.
I don't know this is a correct logic or not but works for me, any other suggestions are welcome.
$extSeat = DB::table('bookings')->select('seat')->first();
$extSeat = explode(",", $extSeat->seat);
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id],
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => implode(",", array_merge($seat,$extSeat )),
'price' => $request->price,
'profile' => 'pending',
]);
I need to save multiple rows with the different condition for each row.
Like :
Update orderdetails SET data = "'.$json1.'" WHERE order_id = 1;
Update orderdetails SET data = "'.$json2.'" WHERE order_id = 2;
Update orderdetails SET data = "'.$json3.'" WHERE order_id = 3;
Update orderdetails SET data = "'.$json4.'" WHERE order_id = 4;
Update orderdetails SET data = "'.$json5.'" WHERE order_id = 5;
I know the single row updation method of CakePHP, that I can run 5 times form to update all row.
But I want to save this by just only one line code that can run above query.
My Code
$update = array(
array('data' => $json1,'order_id' => 1),
array('data' => $json2,'order_id' => 2),
array('data' => $json3,'order_id' => 3),
array('data' => $json4,'order_id' => 4),
array('data' => $json5,'order_id' => 5)
);
$this->Orderdetail->saveMany($update);
So, is there any way in CakePHP to achieve it...?
If I understand the above problem currently, you can achieve this by using the saveMany function in cakePHP. All you have to do is convert the data that you want to save in the form of an array and pass that single array to the saveMany function.
See here for more details
Here is a code sample for the above details in cakePHP 3:
$saveData = [
[
'order_id' => 1,
'data' => $json1
],
[
'order_id' => 2,
'data' => $json2
],
[
'order_id' => 3,
'data' => $json3
],
[
'order_id' => 4,
'data' => $json4
],
[
'order_id' => 5,
'data' => $json5
]
];
$orderDetails = TableRegistry::get('Orderdetails');
$entities = $orderDetails->newEntities($saveData);
$result = $orderDetails->saveMany($entities);
For cakePHP 2.x:
See here for more details
Hope this is what you are looking for.
Edit: Based on the updated requirements, I guess the only way to achieve it is to make a custom query by using the Model->query method. You'll have to form a custom query for that which updates all the records in one go.
I am inserting multiple rows at the same time, say 2 rows
$multiple_rows = [
['email' => 'taylor#example.com', 'votes' => 0],
['email' => 'dayle#example.com', 'votes' => 0]
];
DB::table('users')->insert($multiple_rows);
How can I get those inserted ids.
I am doing it, this way for now.
foreach($multiple_rows as $row){
DB::table('users')->insert($row);
$record_ids[] = DB::getPdo()->lastInsertId();
}
Any other good way to do it, without inserting single row each time.
You could do something like the following:
$latestUser = DB::table('users')->select('id')->orderBy('id', 'DESC')->first();
$multiple_rows = [
['email' => 'taylor#example.com', 'votes' => 0],
['email' => 'dayle#example.com', 'votes' => 0]
];
DB::table('users')->insert($multiple_rows);
$users = DB::table('users')->select('id')->where('id', '>', $latestUser->id)->get();
If you really need all the inserted ID's
$dataArray = [
['name' => 'ABC'],
['name' => 'DEF']
];
$ids = [];
foreach($dataArray as $data)
{
$ids[] = DB::table('posts')->insertGetId($data);
}
To get all id with a massive insertion I think the good way is to first get the last id in the table, make the massive insertion and get the last id. In theory they must follow, unless there has been an insertion from another connection. To avoid that the solution is a transaction.
Update
Also read the documentation