OR clause in Zend DB update? - zend-framework

I'd like to do a Zend db update with an OR clause. What would be the equivalent statement to:
UPDATE mail
SET message_read = 1
WHERE id = 5
OR id = 10

When calling Zend_Db_Adapter::update(), multiple WHERE conditions will automatically be combined using AND (line 698 of Zend/Db/Adapter/Abstract.php in function _whereExpr).
You can get around this by creating your own Zend_Db_Expr which you will use as the WHERE condition and it will be left untouched.
For example:
$where[] = new Zend_Db_Expr(
$table->getAdapter()->quoteInto('id = ?', 5) . ' OR ' .
$table->getAdapter()->quoteInto('id = ?', 10)
);
// resulting expression:
// WHERE (id = 5 OR id = 10)
$table->update($data, $where);
If you had additional WHERE conditions, they would be combined with the OR condition by an AND.
Example:
$where[] = new Zend_Db_Expr(
$table->getAdapter()->quoteInto('id = ?', 5) . ' OR ' .
$table->getAdapter()->quoteInto('id = ?', 10)
);
$where[] = $table->getAdapter()->quoteInto('type = ?', 'sometype');
// resulting expression:
// WHERE (id = 5 OR id = 10) AND (type = 'sometype')

->where() will add a where clause to the query and will put an 'AND'. There is an orWhere method that exists to do that.
$select = $this->select();
$select->where('id = 5');
$select->orWhere('id = 10');
$this->fetchAll($select);

Related

Zend 2: How do I execute multiple SQL queries using Zend\Db\Adapter?

Im executing this query:
$query = "
Select * From table1 Where id = 1;
Select * From table2 Where name = 'test';
";
With \Zend\Db\Adapter\Adapter:
$stmt = $this->dbAdapter->query($query);
$rawResult = $stmt->execute();
How can I access the second result?
$rawResult->next() only returns values from first query.
Use two different queries.
/*
* First Query
*/
$query = "
Select * From table1 Where id = 1
";
$stmt = $this->dbAdapter->query($query);
$rawResult = $stmt->execute();
/*
* Second Query
*/
$query = "
Select * From table2 Where name = 'test'
";
$stmt = $this->dbAdapter->query($query);
$rawResult = $stmt->execute();
I don't believe it works the way you had it to where two queries in a row are sent this way.
To avoid code duplication you can wrap the duplicated code into a method.
$rawResult1 = $this->getResults("Select * From table1 Where id = 1");
$rawResult2 = $this->getResults("Select * From table2 Where name = 'test'");
function getResults(string $query)
{
$stmt = $this->dbAdapter->query($query);
return $stmt->execute();
}

sqli sum of a column codes not working

I am trying to sum of a column of database table by the following cods, but it's not working:
$sqli = "SELECT sum(total_salary) AS totSalary FROM allsalary WHERE month_session = '$month_name' and org_session = '$org_name' and desig_session = '$desig_name' ORDER BY ID ASC ";
$stmt = $mysqli->prepare($sqli);
$stmt->execute();
$stmt->store_result();
$totl = $stmt->fetch();
$total_salary = $totl['totSalary'];
echo $total_salary;
But I could fetch the table correctly.
Now I want to sum the column named 'total_salary', I need a suggestion.....
You are missing two essential functions here, bind_param() and bind_result()
$sql = "SELECT sum(total_salary) FROM allsalary WHERE month_session = ?
and org_session = ? and desig_session = ? ORDER BY ID ASC";
$stmt = $mysqli->prepare($sql);
$sttmt->bind_paran("sss",$month_name,$org_name,$desig_name);
$stmt->execute();
$stmt->bind_result($total_salary);
$stmt->fetch();
echo $total_salary;

Doctrine Datetime and where condition

I am writing a Doctrine 2.3 Query and I am facing some issues:
The SQL Query which I am reflecting was:
SELECT *
FROM `entry`
WHERE `plate` LIKE '%'
AND `recognition_datetime` BETWEEN '2013-03-13 22:20:18'
AND '2013-03-13 22:20:20';
I am getting the out put with the rows selected.
Doctrine which I am trying:
Opt 1:
$qry = $this->manager()->createQueryBuilder()
->from($this->entity, 'e')
->select('e');
$qry->where('e.plate like :plate');
$qry->setParameter('plate', $plate);
$qry->add('where', "e.datetime between '2013-03-13 22:20:18' and '2013-03-13 22:20:20'");
$qry->setMaxResults( $limit );
It out puts only the first where condition:
SELECT e FROM Myproject\Domain\result e WHERE e.plate like '%'
Opt 2:
$qry = $this->manager()->createQueryBuilder()
->from($this->entity, 'e')
->select('e');
$qry->where('e.plate like :plate');
$qry->setParameter('plate', $plate);
$qry->andWhere('e.datetime BETWEEN :monday AND :sunday')
->setParameter('monday', $fromdate->format('Y-m-d H:i:s'))
->setParameter('sunday', $todate->format('Y-m-d H:i:s'));
It prints only the second where as query. Can some one help me how to write multiple where/And/or condition?
After some Research I found few thing which solved my problems:
Query Generation:
//CREATING QUERY BUILDER
$qry = $this->manager()->createQueryBuilder()
->from('YOUR_ENTITY_HERE', 'e')
->select('e');
//LIKE
$ex1 = $qry->expr()->like('e.user', "'".$user."'");
//BETWEEN
$ex2 = $qry->expr()->between('e.datetime',"'".$datetime."'","'".$dateto."'");
//IN
$ex3 = $qry->expr()->in('e.country', $country);
//ADDING ALL EXPRESSION TO ONE INBETWEEN EXPRESSION "AND" OPERATION
$Query = $qry->expr()->andX($ex1,$ex2,$ex3);
//ADDING ALL EXPRESSION TO ONE INBETWEEN EXPRESSION "OR" OPERATION
$Query = $qry->expr()->orX($ex1,$ex2,$ex3);
//ADDING TOTAL EXPRESSIONS TO WHERE
$qry->where($Query);
//GENERATE QUERY
$qry->getQuery();
//FINAL OPERATIONS
//EXECUTE
$qry->execute();
//GET ARRAY OUT PUT
$qry->getArrayResult();
//GET DB OBJECT
$qry->getResult();
Other Methods for Providing IN Operations:
OTHER WAY TO USE IN OPERATION:
$country=array('Us','UK','IND','BE');
$exp = $this->manager()->getExpressionBuilder();
$qry = $this->manager()->createQueryBuilder()
->select('e')
->from('YOUR_ENTITY_HERE', 'e')
->add('where', $exp->in('e.country', $country));

Zend_DB subselect / subquery how to?

I have this raw sql statement which I am trying to execute through Zend_DB.
$sql = 'SELECT relocationaction.id, relocationaction.vehicle, relocationaction.start, relocationaction.end, relocationaction.return ' .
'FROM relocationaction,
(SELECT vehicle, MAX(end) AS maxend
FROM relocationaction
GROUP BY vehicle) AS co2
WHERE co2.vehicle = relocationaction.vehicle
AND(relocationaction.monitor = 1)
AND (relocationaction.return IS NULL)
AND (start <= ?)
AND relocationaction.end = co2.maxend';
I have found a possible solution using this type of notation, but it is rendered to a totally different and wrong sql statement with joins and strange table names.
$tbl = $this->getDbTable();
$select = $tbl->select()->setIntegrityCheck(false);
$subSelect = $select->from('relocationaction', array('vehicle', 'maxend' => 'MAX(relocationaction.end)'))
->group('vehicle');
$subSelectString = '(' . $subSelect->__toString() . ')';
$select ->from(
array('relocationaction'), array('id', 'date' => 'start', 'enddate' => 'end', 'return'),
array('co2' => $subSelectString)
)
->joinLeft('exhibitvehicle', 'exhibitvehicle.id = relocationaction.vehicle', array())
->where('co2.vehicle = relocationaction.vehicle')
->where('relocationaction.monitor = 1')
->where('relocationaction.return IS NULL')
->where('start <= ?', $start->get('yyyy-MM-dd'))
->where('relocationaction.end = co2.maxend');
Can anyone please give me a hint?
Thanks
Jesse
UPDATE
This is the result of the second expression (total rubbish)
SELECT `relocationaction`.`vehicle`,
MAX(relocationaction.end) AS `maxend`,
`relocationaction_2`.`id`,
`relocationaction_2`.`start` AS `date`,
`relocationaction_2`.`end` AS `enddate`,
`relocationaction_2`.`return`
FROM `relocationaction`
INNER JOIN `(
SELECT ``relocationaction``.``vehicle``,
MAX(relocationaction.end) AS ``maxend`` FROM ``relocationaction`` GROUP BY ``vehicle``)`.`relocationaction` AS `relocationaction_2`
LEFT JOIN `exhibitvehicle` ON exhibitvehicle.id = relocationaction.vehicle
WHERE (col2.vehicle = relocationaction.vehicle)
AND (relocationaction.monitor = 1)
AND (relocationaction.return IS NULL)
AND (start <= '2013-05-08')
AND (relocationaction.end = col2.maxend)
GROUP BY `vehicle`
If you use a string in from(), Zend_Db_Select will consider it to be a table name so it escapes it.
The solution is to wrap your subselect into a Zend_Db_Expr.
$tbl = $this->getDbTable();
$select = $tbl->select()->setIntegrityCheck(false);
$subSelect = $select->from('relocationaction', array('vehicle', 'maxend' => 'MAX(relocationaction.end)'))
->group('vehicle');
$subSelectString = '(' . $subSelect->__toString() . ')';
$select ->from(
array('relocationaction'), array('id', 'date' => 'start', 'enddate' => 'end', 'return'),
array('co2' => new Zend_Db_Expr($subSelectString))
)
->joinLeft('exhibitvehicle', 'exhibitvehicle.id = relocationaction.vehicle', array())
->where('co2.vehicle = relocationaction.vehicle')
->where('relocationaction.monitor = 1')
->where('relocationaction.return IS NULL')
->where('start <= ?', $start->get('yyyy-MM-dd'))
->where('relocationaction.end = co2.maxend');
Ok here we go. I tried hard to find a solution with Zend_Db_Table but failed big time. That's why I finally did it with PDO, as suggested by #user466764. Thanks for your help.
$tbl = $this->getDbTable();
$query = 'SELECT relocationaction.id,
relocationaction.vehicle,
relocationaction.start,
relocationaction.end,
relocationaction.return
FROM relocationaction
(SELECT vehicle, MAX(end) AS maxend
FROM relocationaction
GROUP BY vehicle) AS co2
WHERE co2.vehicle = relocationaction.vehicle
AND(relocationaction.monitor = 1)
AND (relocationaction.return IS NULL)
AND (start <= "' . $start->get('yyyy-MM-dd') . '")
AND relocationaction.end = co2.maxend';
$sth = $tbl->getAdapter()->prepare($query);
$sth->execute();
$entries = $sth->fetchAll();

How do I add complex where clause to Zend Table Select?

I searched the Web and could not find anything that would show me a good solid example. My question is basically this:
How do I convert this:
SELECT * FROM table WHERE ((a = 1 AND b = 2) OR (c = 3 OR c = 4)) AND d = 5;
To Zend syntax similar to this:
$this
->select()
->from($this->_schema.'.'.$this->_name)
->where('a = ?', '1');
So how can it be done?
Thank a lot in advance.
I had a similar problem. See the code example in the answer here: Grouping WHERE clauses with Zend_Db_Table_Abstract
So you would end up with something like:
$db = $this->getAdapter();
$this->select()
->where('(' . $db->quoteInto('a = ?', 1) . ' AND ' . $db->quoteInto('b = ?', 2) . ') OR (' . $db->quoteInto('c = ?', 3) . ' OR ' . $db->quoteInto('c = ?', 4) . ')')
->where('d = ?', 5);
Which would give you:
SELECT `table_name`.* FROM `table_name` WHERE ((a = 1 AND b = 2) OR (c = 3 OR c = 4)) AND (d = 5)
1) Build a condition for all groups Where/orWhere:
$conditions = $this->select()
->where('a= ?', 5)
->orWhere('b= ?', 6)
->getPart(Zend_Db_Select::WHERE);
// result: $conditions = "(a= 5) OR (b= 6)";
Use getPart() method to get the where condition.
2) Next, reset the where part of current select object:
$this->select()->reset(Zend_Db_Select::WHERE);
3) Finally, use where condition as you want:
$this->select()
->where('d= ?', 5)
->where(implode(' ', $conditions));
http://framework.zend.com/manual/1.12/ru/zend.db.select.html
Per a message board post on the Zend Framework website, this may not be possible.
It seems to me that where() and orWhere() in the Zend_Db_Select class are not enough to be able to write all queries. It does not support the nesting of conditions, which doesn't enforce the user with abstraction in somewhat more complex cases. With where() and orWhere() I cannot write this:
Edit
The array functionality of Zend_Db_Select->where is designed only for using it with the IN clause.
Example #17 Example of an array parameter in the where() method
// Build this query:
// SELECT product_id, product_name, price
// FROM "products"
// WHERE (product_id IN (1, 2, 3))
$productIds = array(1, 2, 3);
$select = $db->select()
->from('products',
array('product_id', 'product_name', 'price'))
->where('product_id IN (?)', $productIds);
Original
As Peder said you can't nest orWhere but you can pass multiple arguments into where and orWhere.
$this->select()
->from($this->_schema.'.'.$this->_name)
->where(' ( a = ? AND b = ? ) OR ( c = ? OR c = ? ) ', array(1,2,3,4))
->where('d = ?',array(5));