Symfony2 & Doctrine: Create custom SQL-Query - php

How can I create a custom SQL query in Symfony2 using Doctrine? Or without Doctrine, I don't care.
Doesn't work like this:
$em = $this->getDoctrine()->getEntityManager();
$em->createQuery($sql);
$em->execute();
Thanks.

You can get the Connection object directly from the Entity Manager, and run SQL queries directly through that:
$em = $this->getDoctrine()->getManager(); // ...or getEntityManager() prior to Symfony 2.1
$connection = $em->getConnection();
$statement = $connection->prepare("SELECT something FROM somethingelse WHERE id = :id");
$statement->bindValue('id', 123);
$statement->execute();
$results = $statement->fetchAll();
However, I'd advise against this unless it's really necessary... Doctrine's DQL can handle almost any query you might need.
Official documentation: https://www.doctrine-project.org/projects/doctrine-dbal/en/2.9/reference/data-retrieval-and-manipulation.html

You can execute this code it works :
$em = $this->getDoctrine()->getEntityManager();
$result= $em->createQuery($sql)->getResult();

Related

Alternative for fetchAllAssociative()` and execute in doctrine

I am calling a stored procedure using native sql via doctrine. fetchAllAssociative() and execute are deprecated. What are the alternatives?
$sql = 'CALL spWithParams(:param)';
$stmt = $this->getEntityManager()->getConnection()->prepare($sql);
$stmt->execute([":param"=>"test"]);
print_r($stmt->fetchAllAssociative());
I am not planning to map the response to entity using ResultSetMapping() as mentioned here as I will add my custom wrapper on it.
The right way of doing this is to use a ResultSetMapping with scalar results to select arbitrary fields. You can then execute the query with getArrayResult() to achieve the same behaviour as in the provided code.
As an example:
$rsm = new ResultSetMapping();
$rsm->addScalarResult('my_database_column', 'myField');
$query = $this->getEntityManager()->createNativeQuery(
'CALL spWithParams(:param)',
$rsm
);
$query->setParameters([":param"=>"test"]);
$results = $query->getArrayResult();
/*
[
['myField' => 'foo'],
['myField' => 'bar']
]
*/

Symfony2 get new value after UPDATE query

in my Symfony2.8 app I got the following controller:
public function changetariffAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$user = $this->container->get('security.context')->getToken()->getUser();
$userid = $user->getId();
$tariff = $user->getTariff();//tariff1 here
$paymentForm = $this->createPaymentForm($user);
$paymentForm->handleRequest($request);
if($tariff != 'tariff2') {
$query = $em->createQuery('UPDATE My\UserBundle\Entity\User u SET u.tariff = :tariff2 WHERE u.id = :userid');
$query->setParameter('userid', $user->getId());
$query->setParameter('tariff2', 'tariff2');
$query = $query->getResult();//returns 1 here, tariff field in DB is set to tariff2 as expected
$query = $em->createQuery('SELECT u FROM My\UserBundle\Entity\User u WHERE u.id = :userid');//getting once again user entity but it did not change
$query->setParameter('userid', $user->getId());
$user = $query->getResult();
$tariff_upd = $user[0]->getTariff();//tariff1 here but I need tariff2!
//Also I tried to persist and flush user entity here but it did not work
return $this->render('MyBundle:Pages:tariffchangesuccess.html.twig', array(
'user' => $user,
'form' => $paymentForm->createView(),
'tariff' => $tariff_upd //still tariff1 but I need tariff2
));
}
return $this->render('MyBundle:Pages:tariffchangesuccess.html.twig', array(
'user' => $user,
'form' => $paymentForm->createView(),
'tariff' => $tariff
));
}
My Controller works ok and all the values are updated in my DB as expected but new values (tariff2) are not rendered in my twig template. New values are rendered only when I update the page in my browser (hit F5), but this is not an expected behavior. Any ideas how to fix that? Thank you.
Doctrine use something similar as cache and maybe your use of queries instead of natives methods short-circuit this system. Docrtine can handle your entities and know what to record and has been changed etc. But you have to use Doctrine functions or repositories for that, and not do it througt custom queries... The Doctrine way should be something like:
$em = $this->getDoctrine()->getManager();
$userid = $this->container->get('security.context')->getToken()->getUser()->getId()
// Get object user from DB values
$user = $em->getRepository('My\UserBundle:User')->findOneById($userid );
// Update tarif in the user object
$user->setTariff('tariff2');
// Let Doctrine write in the DB. The persist() may not be necesary as Doctrine already manage this object, but it's a good practise.
$em->persist($user);
$em-> flush();
// Doctrine should already have update the $user object, but if you really really want to be sure, you can reload it:
$user = $em->getRepository('My\UserBundle:User')->findOneById($userid );
You can use the refresh method of the EntityManager in order to:
Refreshes the persistent state of an entity from the database,
overriding any local changes that have not yet been persisted.
So add the refresh call, as example:
$query = $em->createQuery('SELECT u FROM My\UserBundle\Entity\User u WHERE u.id = :userid');//getting once again user entity but it did not change
$query->setParameter('userid', $user->getId());
$user = $query->getResult();
// Force refresh of the object:
$em->refresh($user);
$tariff_upd = $user[0]->getTariff();//tariff1 here but I need tariff2!
Hope this help

Mapping doctrine native query to none Entity model class

I am trying to use native query in doctrine and for now created something really simple:
$rsm = new ResultSetMapping();
$rsm->addEntityResult('ObjectA', 'a');
$rsm->addFieldResult('a', 'id', 'id');
$query = $em->createNativeQuery('SELECT * FROM table a', $rsm);
What I try using this code, I am getting an error that ObjectA is not a valid entity or mapped super class. Which is totally true.
My question is: Is there any way to mad result of a native query to any arbitrary class (not Entity), but still user Doctrine's tools to do it.
Note: I am trying to avoid usage of lower level PDO.
Thank you.
Nothing like that, neither in the doc nor in the source code Doctrine\ORM\Query\ResultSetMapping (and it happens that some features are not documented).
I'd go with using scalar results and mapping the query result back to the object. Something like this:
$rsm = new ResultSetMapping();
$rsm->addScalarResult('a', 'a');
$rsm->addScalarResult('b', 'b');
$query = $em->createNativeQuery('SELECT a, b FROM table LIMIT 1', $rsm);
$result = $query->getSingleResult();
$a = new ObjectA();
$a->setA($result['a']);
// or
$a = new ObjectA($result); // with mapping passed to the constructor

how to get result from createNativeQuery?

I'm building a zend framework 2 application with php 5.6
I'm using doctrine2 for the database related code.
I created Yaml files for each table in the database.
I'm trying to call a query and return it's result.
I'm using the following code:
$query=<<<EOS
QUERY...
EOS;
$objectManager=$this->getObjectManager();
$rsm = new ResultSetMapping();
$rsm->addEntityResult( 'MyAlcoholist\Entity\DrinkFlavorInfo','u');
$rsm->addFieldResult('u','drink_type_name','drinkTypeName');
$rsm->addFieldResult('u','drink_brand_name','drinkBrandName');
$rsm->addFieldResult('u','drimk_company_name','drinkCompanyName');
$rsm->addFieldResult('u','drink_flavor_type_name','drinkFlavorTypeName');
$query = $objectManager->createNativeQuery($query,$rsm);
$query->setParameter(1, $id);
$drinkFlavors = $query->getResult();
die(var_export($drinkFlavors,1));
I created a class called DrinkFlavorInfo with getters and setters for the variables but since i configured doctrine to work with yaml then it's searching for a yaml file instead.
in yaml configuration one of the properties is table_name and there is no table, i'm just trying to create a class that will hold the returned values. how can i do so?
ok so it appears that this is how i should have defined the columns and execute the query:
$objectManager=$this->getObjectManager();
$rsm = new ResultSetMapping();
$rsm->addScalarResult('drink_brand_name','drinkBrandName');
$rsm->addScalarResult('drink_type_name','drinkTypeName');
$rsm->addScalarResult('drink_flavor_type_name','drinkFlavorTypeName');
$rsm->addScalarResult('drink_company_name','drinkCompanyName');
$query = $objectManager->createNativeQuery($query,$rsm);
$query->setParameter(1, $id);
$drinkFlavors = $query->getArrayResult();
die(var_export($drinkFlavors,1));
this works :)

PHP: Symfony2 MySQL SELECT query in controler

I created a database on phpMyAdmin localhost. I have set database configurations in symfony and created doctrine mapper (entity). Now all I need is to make SELECT query and get information from database:
TABLE NAME: Profile
ROWS: 1
CONTROLLER CODE:
...
use Ignas\IgnasBundle\Entity\Profilis;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
$profilis = new Profilis();
return new Response('Id '.$profilis->getId());
}
}
getId method is from Entity/Profilis file Profilis class.
Is there any easy way to do this? I searched for a while and all I could find was doctrine syntax that is not familliar to me at all.
you can do it in different ways:
first of all, get the EntityManager in your Controller
$em = $this->getDoctrine()->getEntityManager();
in case it says it's deprecated you can also get it like:
$em = $this->getDoctrine()->getManager();
then you can do it with the QueryBuilder or with the createQuery method
With Select method (as suggested in the comments)
$profilis= $em->select('p.id')
->from('BundleName:EntityName', 'p')
->getQuery()
->getResult();
simple Query:
$query = $em->createQuery("SELECT * FROM Profilis p");
$profilis = $query->getResult();
NOTE
both methods return an array of Profilis so you can simply loop them this way:
foreach($profilis as $p){
// do whatever you want
}

Categories