I try to delete some data with Doctrine\DBAL\Connection, I want to delete the duplicate data so I have to delete n-1 data (If n data are the same).
public function deleteDuplicateData(array $data) : bool
{
$qb = $this->connection->createQueryBuilder();
$qb->delete('myTable')
->where('id= :id')
->setParameter('id', $data['id'])
->setMaxResults($data['n']-1)
;
return $qb->execute();
}
However the ->setMaxResults($data['n']-1) doesn't work, when I run my code all data are deleted. I tried this ->setMaxResults($data['n']-1) but it does'nt work so I think the method ->setMaxResults() doesn't work for the delete method.
I cant comment, so sry for this ^^
Is it possible to count the rows with duplicate data in your DB System + Do they have the same ID? If yes, you could store the ammount - 1 to a variable $duplicatedRows and use a for loop like:
for($i;$<=$duplicatedRow;$i++){
//Your Code to delete something
}
setMaxResults works only in some cases. It seems to ignore it if it's not managed.
check the Doctrine doc : https://www.doctrine-project.org/projects/doctrine1/en/latest/manual/dql-doctrine-query-language.html#driver-portability
use below function for set limit
public function deleteDuplicateData(array $data) : bool
{
$limit = 10;
$qb = $this->connection->createQueryBuilder();
$qb->delete('myTable')
->where('id= :id')
->setParameter('client_id', $data['id'])
->setMaxResults($limit);
return $qb->execute();
}
Related
I tried to fetch data using joins and the data is repeating,
The controller code is:
public function searchjobs2()
{
//$id=$_SESSION['id'];
$lan = $_POST["picke"]; //var_dump($id);die();
$value['list']=$this->Free_model->get_jobs($lan);//var_dump($value);die();
$this->load->view('free/header');
$this->load->view('free/searchjobs2',$value);
}
And the model:
public function get_jobs($lan)
{
$this->db->select('*');
$this->db->from("tbl_work_stats");
$this->db->join("tbl_work", "tbl_work.login_id = tbl_work_stats.login_id",'inner');
$this->db->where("language LIKE '%$lan%'");
// $this->db->where('tbl_work_stats.login_id',$id);
$this->db->order_by('insertdate','asc');
$query=$this->db->get()->result_array();//var_dump($query);die();
return $query;
}
I have used
foreach ($list as $row){
...
}
for listing.
Using distinct will remove duplicate fields:
$this->db->distinct();
From what I can see, your query has ambiguity, and an error in the join statement, also your where like is part of the problem, I would recommend trying this even do there are some missing info, find out wich field you need to join from the second table.
public function get_jobs($lan){
$this->db->select("tbl_work_stats.*, tbl_work.fields");
$this->db->from("tbl_work_stats");
$this->db->join("tbl_work", "tbl_work_stats.login_id = tbl_work.login_id","inner");
$this->db->where("tbl_work.language LIKE", "%" . $lan . "%" );
$this->db->order_by("tbl_work_stats.insertdate","asc");
$query=$this->db->get()->result_array();
return $query;}
do you mean to join on login_id?
I am guessing that is the user logging in and it is the same for many entries of tbl_work_stats and tbl_work.
you didn't post your schema, , but login_id doesn't seem like right thing to join on. how about something like tbl_work.id = tbl_work_stats.tbl_work_id or similar?
also CI $db returns self, so you can do:
public function get_jobs(string $lan):array
{
return $this->db->select()
->from('tbl_work_stats')
->join('tbl_work','tbl_work.id = tbl_work_stats.work_id')
->like('language',$lan)
->order_by('insertdate')
->get()
->result_array();
}
How can I rewrite this code in order to get last inserted record from the table?
$repository = $entityManager->getRepository('AdminBundle:MyTable');
$product = $repository->find($id);
I tried something like
$repository->findBy(array('id','DESC')->setMaxResults(1);
But it did not work for me.
You could get the latest record by using findBy() with order by, limit and offset parameters
$results = $repository->findBy(array(),array('id'=>'DESC'),1,0);
First argument is for filter criteria
Second argument takes order by criteria
Third argument is for limit
Fourth argument sets offset
Note it will return you the results set as array of objects so you can get single object from result as $results[0]
FindBy() Examples
Instead of hacking code where you want to use it, you can also create a repository method and call it when necessary.
/**
* Repository method for finding the newest inserted
* entry inside the database. Will return the latest
* entry when one is existent, otherwise will return
* null.
*
* #return MyTable|null
*/
public function findLastInserted()
{
return $this
->createQueryBuilder("e")
->orderBy("id", "DESC")
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
References:
https://symfony.com/doc/current/doctrine.html#querying-for-objects-the-repository
After looking for one I decided to try it myself, I think it was much less verbose:
$myRepository->findOneBy([], ['id' => 'DESC']);
Please try the below one
$repository = $entityManager->getRepository('AdminBundle:MyTable');
$repository->setMaxResults(1)->orderBy('id', 'DESC');
$results = $repository->getQuery()->getSingleResult();
Reference:
https://undebugable.wordpress.com/2016/01/27/symfony2-querybuilder-find-first-and-find-last-record-in-table/
You can add these functions to your repository:
public function getLastRow(): ?YourEntity
{
return $this->findOneBy([], ['id' => 'DESC']);
}
public function getLastId(): int
{
$lastRow = $this->getLastRow();
return $lastRow ? $lastRow->getId() : 0;
}
You can be collected by getting the id of the inserted object
$em->persist($entity);
$em->flush();
$entity->getId();
OR
$entitymanager->getRepository("entity")->findBy([],["id"=>desc])->getId();
I want to delete some data and return the number of the deleting.
This is my code :
public function deleteMyData() : ?int
{
$qb = $this->connection->createQueryBuilder()
->delete('myTable')
->where('pays ="us"')
;
return $qb->execute()->rowCount();
}
I already tested other things like :
->delete()
->from('myTable')
->where('pays ="fr"')
When I run my code I've got this error :
[Symfony\Component\Debug\Exception\FatalThrowableError]
Call to a member function rowCount() on integer
I dumped $qb->execute()->rowCount() and it return "0".
Thanks for your help !
PS : I think that the problem isn't the query because :
Error An exception occurred while executing 'DELETE FROM theQueryTest WHERE pays ="us"':
The SQL is great
PS 2 : I can't use ->getQuery()
This code returns an integer
return $qb->execute();
If you want to count row affected try this:
$qb = $this->createQueryBuilder();
//query
$count = $qb->getQuery()->getSingleScalarResult();
I found the solution
In my case, I have to use $this->connection HOWEVER I don't have to use $qb->execute()
I read the doc and I found this in Connection.php (->delete(...)) :
#return integer The number of affected rows.
So I have to use directly $this->connection->delete(...)
public function deleteMyData() : ?int
{
$qb = $this->connection
->delete('myTable', ['pays' => '"us"'])
;
return $qb;
}
In my symfony project I have two entities that are related via one to many.
I need to find the first and last child, so I use repository functions that look like this:
public function getFirstPost(Topic $topic)
{
$query = $this->createQueryBuilder('t')
->addSelect('p')
->join('t.posts', 'p')
->where('t.id = :topic_id')
->setParameter('topic_id' => $topic->getId())
->orderBy('p.id', 'ASC')
->setMaxResults(1)
->getQuery();
return $query->getOneOrNullResult();
}
public function getLastPost(Topic $topic)
{
$query = $this->createQueryBuilder('t')
->addSelect('p')
->join('t.posts', 'p')
->where('t.id = :topic_id')
->setParameter('topic_id' => $topic->getId())
->orderBy('p.id', 'DESC')
->setMaxResults(1)
->getQuery();
return $query->getOneOrNullResult();
}
So the only difference is in in ->orderBy(), for the first Post I use ASC and for the last I use DESC.
Now If I use one of those functions from my controller, the return the expected result and work just fine. But If I run them both at the same time from my controller, they return the same result, which they shouldn't.
My guess is that Doctrine caches these queries and the results somehow and that's why the return the same so I tried using $query->useResultCache(false) but that didn't do anything.
So my question is, why is this happening and how can I fix it?
Well, it is cache issue indeed, but mostly it is query issue. Instead of returning a post in these function you return the whole topic with joined posts.
What you can do is to rewrite these queries to select Post entity directly and join Topic entity to it which will be filtered by.
If you really(dont do this) need these queries to work you can detach first topic returned by one of those methods and then call the other method:
$this->getDoctrine()->getManager()->detach($firstTopic);
I have one MongoDb document with 3 fields message, author, sendAt, i have created a query builder to count all DB entries on this document and if there is more than 20 entries, I'm trying to delete the oldest one.
sendAt is the current dateTime when the message is send ("sendAt" : ISODate("2016-01-21T08:53:00Z"))
I have an unfinished query builder
public function deleteOldestMessage()
{
return $this->createQueryBuilder()
->delete('m')
->from('Messages', 'm')
->where('m.sendAt = ')
->execute();
}
But i really don't know what i should add on the where condition.
I should maybe order DESC the sendAt field and delete the first on the list ?
How can I tell the query builder to delete the oldest one ?
Thanks,
You need first to select the oldest one then you can delete it like this :
$qb->select('m')
->from('Messages', 'm')
->orderBy('m.sendAt', 'DESC');
$messages = $qb->getResult();
thene
if(count($messages) >= 20){
//get the first element of array which is the oldest one
$lastMessage = current($messages);
$em->remove($lastMessage);
}
You can try something like:
$qb = $em->createQueryBuilder();
$messages = $qb->select('m')
->from('Messages', 'm')
->orderBy('m.sendAt', 'ASC')
->getQuery()
->getResult()
;
// You will receive array where in the top will be the oldest message.
if (count($messages) > 20) {
// And in your desired case, you can remove just one oldest message.
$messageToDelete = array_shift($messages);
$em->remove($lastMessage);
$em->flush();
}
You use sql query builder options instead of mongodb.
return $this->createQueryBuilder()
->remove()
->sort('sendAt', 'asc')
->getQuery()
->getSingleResult()
->execute();