Alternative for fetchAllAssociative()` and execute in doctrine - php

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']
]
*/

Related

ZF2 - TableGateway with Mysqli driver

I am trying to use a TableGateway class in ZF2 with the Mysqli driver but am having loads of problems.
For some reason, any Where clause I add with a variable never gets quoted in and when the query is executed it throws the error:
Statement couldn't be produced with sql: ...
The code that is giving me problems is this:
<?php
class MyTable extends Zend\Db\TableGateway\TableGateway
{
public function get_count($id)
{
$count = $this->select(function (Zend\Db\Sql\Select $select) use ($id) {
$select->columns([
'count' => 'COUNT(field)',
]);
$select->join(['alias1' => 'other_table'], 'thing = alias1.thing', []);
$select->where([
'main_table.id' => $id,
'alias1.active' => 1,
]);
})->current();
return $count;
}
}
When I look at the error, it just shows ? where the actual values supplied should be.
If though, I select straight from the adapter like this:
// build select object similar to above example
$selectString = $sql->getSqlStringForSqlObject($select);
$results = $this->dbAdapter->query($selectString, Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
Then it works perfectly. But I have to use this getSqlStringForSqlObject which I find odd. In my other projects I am using the PDO driver and I never had such an issue but for this project the mysqli driver is required.
How can I make the values supplied to where get quoted in properly?
Try using prepareStatementForSqlObject. Also, if it's possible, please show us your db config.
prepareStatementForSqlObject() will return a StatementInterface object.
getSqlStringForSqlObject() will get you you a plain sql string.

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

Is there a way to prepare a sql statement in prestashop using Db instance?

I want to find something like PDO methods, that works with Prestashop DB Object, or a module, or new class that uses PDO class and prepare the statements before execution.
If I can change the following by something with PDO class
$result = Db::getIntance()->executeS('SELECT * FROM customer WHERE id = '.$id_customer);
I didn't see anything like that and I want to know if exists before make more code without prepare statements
In prestashop you can use ORM like this
Db::getInstance()->insert('target_table', array(
'id_target' => (int)$target,
'name' => pSQL($name),
));
You can use the DbQuery class for a cleaner code
$sql = new DbQuery();
//this line is optional
$sql->select('*');
//PrestaShop will add the prefix to the table
$sql->from('customer');
//or if you want to select specific columns
$sql->select('id_customer, name, etc..');
//each where line is considered as an AND
$sql->where('id = '.(int)$id_customer);
$sql->where('name = '.pSQL('name of customer'));
$result = Db::getIntance()->executeS($sql);

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 :)

Symfony2 & Doctrine: Create custom SQL-Query

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();

Categories