CodeIgniter UPDATE and LIMIT - codeigniter

I know this question has been posted already before Update with limit 1 in codeigniter use active record
But it seems combining UPDATE and LIMIT using Active Record doesnt work on my side. It will still update all record based on the WHERE clause. I'm currently using CodeIgniter 3.0.6. Is this a bug from CodeIgniter already?
screenshot of the query

You cannot directly add limit in update query. I get an alternative way. Firstly you get one row by where query and then run the update query with using fetching row unique key like unique auto increment id.
$singleInfo = $this->db->get_where($tbl, array('user_id'=>1));
$this->db->update($tbl,array('username'=>'FredSmith'),array('user_id'=>$singleInfo->id));

Well I fired up CI 3.0.6 and used this as a demonstration, as we cannot see your setup.
public function db_update_test_with_limit(){
$tbl = 'users';
// Use Chaining - Works
$this->db
->where('user_id',1)
->limit(1)
->update($tbl,array('username'=>'FredSmith'));
echo $this->db->last_query();
// Use discrete calls - Works
$this->db->where('user_id',1);
$this->db->limit(1);
$this->db->update($tbl,array('username'=>'FredSmith'));
echo '<br>';
echo $this->db->last_query();
}
And the results for both are...
UPDATE `users` SET `username` = 'FredSmith' WHERE `user_id` = 1 LIMIT 1
UPDATE `users` SET `username` = 'FredSmith' WHERE `user_id` = 1 LIMIT 1
So if you are doing the same thing and getting different results, then something funky is going on.
If you use this as a test and massage it to suit your situation, does it work or not?

Related

Find max value of a column in laravel

The problem started because I have a table (Clientes), in which the primary key is not auto-incremental. I want to select the max value stored in a column database.
Like this select, but with eloquent ORM (Laravel):
SELECT MAX(Id) FROM Clientes
How can I do this?
I tried:
Cliente::with('id')->max(id);
Cliente::select('id')->max(id);
I prefer not to make a simple raw SELECT MAX(ID) FROM Clientes
I cannot make it.
Thanks all!
The correct syntax is:
Cliente::max('id')
https://laravel.com/docs/5.5/queries#aggregates
Laravel makes this very easy, in your case you would use
$maxValue = Cliente::max('id');
But you can also retrieve the newest record from the table, which will be the highest value as well
$newestCliente = Cliente::orderBy('id', 'desc')->first(); // gets the whole row
$maxValue = $newestCliente->id;
or for just the value
$maxValue = Cliente::orderBy('id', 'desc')->value('id'); // gets only the id
Or, if you have a created_at column with the date you could get the value like this
$maxValue = Cliente::latest()->value('id');
Relevant Laravel Documentation: https://laravel.com/docs/5.5/queries#aggregates
$maxValue = DB::table('Clientes')->max('id');
Cliente::where('column_name', $your_Valu)->max('id') // You get any max column
We can use the following code :
$min_id = DB::table('table_name')->max('id');
https://laravel.com/docs/8.x/queries#aggregates

Laravel Eloquent sql statement after exist check is limited to 1

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.

Eloquent is generating bad update query

I'm trying to update a record just after I get it from database.
$item = Model::find($id);
$item->field = 'foo';
$item->save();
it do finds the requested record, but the query generated to update the record is not correct:
update `Models` set `field` = ? where `id` is null
I don't know why this is happening!
what is wrong ?
Update:
I just renamed the primary-Key from ID to id in the database table. and then it worked! I didn't know it's case-sensitive
update `bannerads_orders` set `ViewedCount` = ? where `id` = ?
Well, I found the problem. as Laravel documents says:
Note: Eloquent will also assume that each table has a primary key
column named id. You may define a primaryKey property to override this
convention
but in my table it was ID not id. so after I changed it to id, everything works as expected.
Laravel uses prepared statements. There is nothing wrong with this. Additionally you don't actually specify an error.
You should probably use in this case:
$item = Model::findOrfail($id);
$item->field = 'foo';
$item->save();
It seems that $id might be null or user cannot be found and than saving it doesn't make any sense.
If user is not found exception will be thrown and this save won't be executed

select_max not working in CI

This is not working in my CI app:
$query = $this->db->select_max('order')->get('posts');
print_r($query);
Why is that?
I have a column in my DB called order (int, where the highest value is currently 6) and the table is called posts
Why nothing is outputted instead a number 6 ?
This just runs the query, you need to use ->row() to get the result from it.
$this->db->select_max('order', 'max_order');
$query = $this->db->get('posts');
echo $query->row()->max_order;
DOCS:
https://www.codeigniter.com/userguide2/database/active_record.html
https://www.codeigniter.com/userguide2/database/results.html

Preventing Doctrine's query cache in Symfony

In my Symfony/Doctrine app, I have a query that orders by RANDOM(). I call this same method several times, but it looks like the query's result is being cached.
Here's my relevant code:
$query = $table->createQuery('p')
->select('p.*, RANDOM() as rnd')
->orderBy('rnd')
->limit(1)
->useQueryCache(null)
->useResultCache(null);
$result = $query->fetchOne();
Unfortunately, the same record is returned every time, regardless of me passing null to both useQueryCache and useResultCache. I tried using false instead of null, but that didn't work either. Lastly, I also tried calling both setResultCacheLifeSpan(0) and setResultCacheLifeSpan(-1), but neither call made a difference.
Any insight on how to prevent caching since I want a different random row to be selected each time I call this method?
Edit: I also tried calling clearResultCache(), but that just ended up causing an error stating: "Result Cache driver not initialized".
Edit 2: As requested, here's the SQL generated by calling $query->getSqlQuery():
SELECT c.id AS c__id, c.name AS c__name, c.image_url AS c__image_url,
c.level AS c__level, c.created_at AS c__created_at, c.updated_at
AS c__updated_at, RANDOM() AS c__0 FROM cards c ORDER BY c__0 LIMIT 1
It turns out I'm a moron. I tried to simplify my query for this question, and in doing so, I didn't capture the true cause. I had a where() and andWhere() call, and the combination of conditions resulted in only one possible record being matched. Thanks for taking the time to respond, everyone, sorry to have wasted your time!
Doctrine also caches entities you created in the same request/script run.
For instance:
$order = new Order();
$order->save();
sleep(10); // Edit this record in de DB in another procces.
$q = new Doctrine_Query();
$result = $q->select()
->from('Order o')
->where('o.id = '.$order->id);
$order = $result->getFirst();
print_r($order->toArray());
The print_r will not contain the changes you made during the sleep.
The following code will remove that kind of memory cache:
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$tables = $connection->getTables();
foreach ( $tables as $table ) {
$table->clear();
}
PS: Added this answer because I found this topic trying to resolve above issue.

Resources