I have this query eloquent in Laravel, I was curious to know. If there is a way to know how many records inserted or how many records ignored to the table?
DB::table('mytable')->insertOrIgnore($data)
Note: One of the manual ways can be, counting records of table before and after process. but this has performance effect, if there be any better way achieving this.
The function insertOrIgnore() returns the affected rows.
/**
* Insert a new record into the database while ignoring errors.
*
* #param array $values
* #return int
*/
public function insertOrIgnore(array $values) {
So you can simply use the returned value and compare it to what was expected to be inserted:
$affected = DB::table('mytable')->insertOrIgnore($data);
$ignored = count($data) - $affected;
Related
This eloquent collection provides this result:
$id = Model::where('s_id', $s_id)->pluck('l_id');
print_r($id)
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => 31242682774
)
)
How do I return only the "31242682774" value as a string and not a collection?
EDIT ANSWER:
All I had to do is:
$id = Model::where('s_id', $s_id)->pluck('l_id')->first();
Any better options?
If you only need a single value, not multiple values, pluck isn't what you want. There is a method called value on Query Builder that returns a single value:
Model::where('s_id', $s_id)->value('l_id');
Laravel 6.x Docs - Query Builder - Retrieving Results - Retrieving A Single Row / Column From A Table value
It compares to when it the process you wanna do it. On the query execution or after. The most common approach would probably be.
$id = Model::where('s_id', $s_id)->first()->l_id;
This will execute after, meaning the query builder will fetch all columns in the row. In general in Laravel you don't that often work with strings and or other abstractions than your model. Model::where('s_id', $s_id)->first() will return your model and select the l_id property on it.
The approach you chosen is the database way, you only select the l_id and return it as a collection and select the first item from there. This is thou a very performance efficient way of doing it since the database does all the work and is very quick at it.
$id = Model::where('s_id', $s_id)->pluck('l_id')->first();
The reason why it is a collection, it is mainly made for selecting multiple id's, so if you query returned multiple rows multiple ids would be returned. Here you can see an example of pluck in conditional queries, where it is most often used.
$teamIds = Team::where('type', 'admin')->pluck('id');
$adminUsers = User::where('team_id', $teamIds)->get();
Your solution is perfect for what you need, just trying to bring clarity on why and a example of how it is often used.
I'm using Doctrine query builder to try to find all occurrences from the last 7 days. Here's my code:
return $this->createPublishedQueryBuilder('content')
->andWhere('content.date BETWEEN :today AND :sevenDaysAgo')
->setParameter('today', new \DateTime())
->setParameter('sevenDaysAgo', new \DateTime('-7 day'))
->orderBy('content.pageviews.weekly', 'desc')
->setMaxResults($count)
->getQuery()
->getResult();
But it's not returning any results. The recently added lines were the andwhere and two setparameter lines below that in order to add the additional search functionality. Any thoughts on what's going on would be greatly appreciated.
EDIT 1:
No luck switching :today AND :sevenDaysAgo
I also forgot to mention here is the date variable:
/**
* #ORM\Column(type="datetime")
*
* #Serial\SerializedName("publication_date")
* #Serial\Type("DateTime<'Y-m-d'>")
* #Serial\Groups({"list", "fixture", "detail", "email"})
*
* #Assert\Date()
*
* #var DateTime
*/
protected $date;
instead of using a between query I would suggest using a higher-than method.
return $this->createPublishedQueryBuilder('content')
->andWhere('content.date > :sevenDaysAgo')
->setParameter('sevenDaysAgo', new \DateTime('-7 day'))
->orderBy('content.pageviews.weekly', 'desc')
->setMaxResults($count)
->getQuery()
->getResult();
otherwise I see no errors in your query. I guess "createPublishedQueryBuilder" is intentional and an abstract form of "createQueryBuilder" ?
Below is my code for deleting all rows with ids one.It seems that only first index was deleted
and an error will trigger right away.How can i loop through the array and delete all rows with id one.
The array I've created here is only a representation from my database with multiple columns.
Any idea in resolving this problem is much appreciated.
public function deleteRow(){
$ids = ['1','1','1','3','3','1','1'];
foreach($ids as $id ){
$id = Scholarshipcount::find($id);
$id->delete();
}
}
my error
Call to a member function delete() on a non-object
Find() can fail to find the record, especially of you have multiple times the same PK as in your example (and you have already deleted the object the first time). You might want to consider using findOrFail instead.
You should use a different kind of approach instead. Assuming that your table name is scholarshipcounts then:
DB::table('scholarhipcounts')->whereIn('id', $ids)->delete();
One of my models contains the following:
public function from()
{
return $this->belongsTo(Station::class, 'from_station_id');
}
public function to()
{
return $this->belongsTo(Station::class, 'to_station_id');
}
In order to use this I'm using the with('to', 'from') method. Which results in the following:
select * from "stations" where "stations"."id" in ('1')
select * from "stations" where "stations"."id" in ('2')
Two cached queries one for "to's" and one for "from's". At the moment with 1 record they are "useful". But in the future they will have a lot of duplicate IDs..
Does Laravel offer an option to combine these?
Assuming you'll need to access them from the model by the relation, like $model->from->first() or $model->to->count(), your best option would be to stick with 2 queries. A query with where in clause is not that heavy and you can additionally cache them to speed up.
I've found a really weird behaviour in the current laravel 4.2 patch. Until now whenever I want to get some datas from my eloquent model I check if results are available before i get them via the following code example:
$foo = $model->hasManyRelationFunction();
if($foo->exists())
foreach($foo->get() as $elem)
....
this results in the following sql statement:
select count(*) as aggregate from "vendor_tabs" where "vendor_tabs"."vendor_id" = '80' limit 1 <-- exist() ?
following by the real select sql statement without Limit 1, for example:
select * from "vendor_tabs" where "vendor_tabs"."vendor_id" = '80' order by "id" asc
Since i've updated laravel 4.2 to the current patch, it also limits the real sql statement to 1
`select * from "vendor_tabs" where "vendor_tabs"."vendor_id" = '80' order by "id" asc` limit 1
but ONLY when I make the if($foo->exists()) check. As soon i comment out the exist condition everything works fine. Are their any informations about this behaviour or am I just stupid? :D
Edit: It seems like they made the eloquent builder "more fluent" in patch 4.2.13. I still dont know if this is a bug or a feature, imo this shouldnt be the normal behaviour.
/**
* Determine if any rows exist for the current query.
*
* #return bool
*/
public function exists()
{
$limit = $this->limit;
$result = $this->limit(1)->count() > 0;
$this->limit($limit);
return $result;
}
In fact you don't need to check existence. You should only do:
foreach ($model->hasManyRelationFunction as $elem) {
// do whathever you want
}
and it's just enough to get the data. You don't need to check existence here or if you think you do, you should show a real example of a code what you are trying to achieve.