codeigniter FIND_IN_SET not working with join - mysql

I have a codeigniter-mysql requirement to select values from table_2 which joins table_1 and need to apply where statement in a comma separated field value. Tried as follows,
$where = $this->db->escape("FIND_IN_SET(table_1.id,table_2.places_id)<>0");
$this->db->select('table_2.*,GROUP_CONCAT(table_1.location)AS location');
$this->db->from('table_2');
$this->db->join('table_1', $where);
$this->db->where('ltable_2.packages_id', $id);
$results = $this->db->get();
return $results->result();
But the above codeigniter db object returns following mysql query and its not working :(
SELECT `table_2`.*, GROUP_CONCAT(table_1.location)AS location FROM `table_2` JOIN `table_1` ON 'FIND_IN_SET(table_1.id,table_2.places_id)<>0' WHERE `ltable_2`.`packages_id` = <id-goes-here>
It seems the quotes around 'FIND_IN_SET(table_1.id,table_2.places_id)<>0' creates the problem! All helps are appreciated to resolve the issue.

You could try $this->db->join('table_1', $where, false);. That would get rid of the quotes, and if otherwise your query is good, it should be fine.

Related

Laravel QueryBuilder - Different result with `where()` and `whereRaw()` for the identical Query

I'm working on a laravel application Where I have two very similar QueryBuilder but producing different result in both conditions.
Query 1:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->whereRaw('feed.active <> agents.feed_status')
->pluck('id');
dd(count($ids)); // print 485236
Query 2:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->where('feed.active', '<>', 'agents.feed_status')
->pluck('id');
dd(count($ids)); // print 4259
I would like to know the key difference between these two QueryBuilder. Why is it producing different results, although it seems identical?
And which query returns the correct result? if I would like to find the records from agents where feed_status is not equel to feed.active.
it seem I have got the clarification. Howevere I would like to share my R&D here. Incase if anyone else got the same problem.
I have printed the raw query and get where() seems consider the third parameter as string compare instead of field compare. That's why seems the result is different.
However when we run the query with whereRaw() it's treated this as table field comparision.
Laravel Code:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->whereRaw('feed.active <> agents.feed_status')
->pluck('id');
MySql Query:
"select * from `agents` left join `feed` on `agents`.`identifier` = `feed`.`identifier` where feed.active <> agents.feed_status"
# where feed.active <> agents.feed_status
Laravel Code:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->where('feed.active', '<>', 'agents.feed_status')
->pluck('id');
MySql Query:
"select * from `agents` left join `feed` on `agents`.`identifier` = `feed`.`identifier` where `feed`.`active` <> 'agents.feed_status'"
# where feed.active <> 'agents.feed_status'
Yes, the results were meant to be different.
As where method compares a column with a literal value
->where('table.column', 'cond', 'value')
If you are looking to make comparisons in two columns without using whereRaw method; you should instead use whereColumn method
->whereColumn('table1.column1', 'cond', 'table2.column2')

Doctrine - SQL Query Builder - update and join?

I use Doctrine's SQL Query Builder (http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html)
and want to do an update case with a join. I understand that a join is not supported here. So I do this:
$query = $dbalQueryBuilder->update('s_articles_attributes', 'aa')
->set('aa.fp_pos_days', ':days')
->where('aa.articledetailsID IN (SELECT a.id FROM s_articles a WHERE a.supplierID IN (:supplierIds))')
->setParameter('days', $days_string)
->setParameter('supplierIds', $supplierIds)
->execute();
$supplierIds is string(39) "3,4,26,28,31,36,37,38,48,49,55,56,64,82"
When I run this query, nothing happens. When I do this:
$query = $dbalQueryBuilder->update('s_articles_attributes', 'aa')
->set('aa.fp_pos_days', ':days')
->where('aa.articledetailsID IN (SELECT a.id FROM s_articles a WHERE a.supplierID IN (3,4,26,28,31,36,37,38,48,49,55,56,64,82))')
->setParameter('days', $days_string)
->execute();
It works fine. Does anybody know why? And that do I do wrong? I need to use that variable...
I did solve it:
I do pass the values as an array now and critical was to declare the type as well:
->setParameter('days', $days_string)
->setParameter('supplierIds', $supplierIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
try to pass an array and not a string to set parameter doctrine know how to map an "in" where clause.
explode your string

Need help on select statement to be used in laravel

select distinct clientID from Client where clientID not in (select clientID from courseDetails inner join course on coursedetails.courseID = course.courseID where coursedetails.courseID = '$courseID')
If your query is a complex one then you can use RAW query in laravel like:
$data = DB::select(DB::raw('your query'));
Reference
Note: DB::raw() is used to make arbitrary SQL commands which aren't parsed any further by the query builder. They therefore can create a vector for attack via SQL injection.
I give you a starting point:
$results = DB::table('Client')
->whereNotIn('clientID', function($query) use ($courseID) {
$query->select('clientID')
->from('courseDetails')
->join('course', 'courseDetails.courseID', '=', 'course.courseID')
->where('coursedetails.courseID', '=', $courseID);
})->get();
This should get you going. You can tweak it as you want to get your expected result.
Adding to #Mayank answer, you can run raw SQL and pass parameter like this
$result = DB::select('select distinct... where coursedetails.courseID = ? ', [$courseID]);

Symfony2: comparing a stored datetime object with the current date with doctrine

I want to compare a stored DateTime entry in my Database with the current date using Doctrine.
I have a list of Keys and their relation to a Person. My goal now is to create a list for available keys or not available keys.
For that I have to look at 2 Tables, key and personToKey. Where personToKey has a field rueckgabe(time to return the key) (dateTime) and a field key (stored id of the key) with an OneToMany Relation to the field id of the Table key.
Thanks to some search here, I got a running SQL Query which gives me the values I am looking for.
SQL Query:
SELECT * FROM key LEFT OUTER JOIN personToKey on key.id = personToKey.KeyId
WHERE personToKey.rueckgabe < NOW()
My Problem is now, that I don't get this to work using doctrine. I had 2 approaches for this.
$qb = $em->createQueryBuilder();
$query = $qb->select('k')
->from('MyBundle:key', 'k')
->leftjoin('MyBundle:personToKey', 'ptk','WITH', 's.id = ptk.key')
->where('ptk.rueckgabe < :date_now')
->setParameter('date_now', date('Y-m-d H:i:m'))
->getQuery();
$test = $query->getResult();
And
$sql = 'SELECT k FROM MyBundle:key k LEFT OUTER JOIN MyBundle:PersonToKey ptk WITH k.id = ptk.key WHERE ( ptk.rueckgabe < CURRENT_DATE()) ';
$query = $em->createQuery($sql);
$test = $query->getResult();
Since the SQL Query works I would have thought that at least the second approach should have worked. But in both cases I get the following results:
for ptk.rueckgabe >= :date_now the list is fine, but for ptk.rueckgabe < :date_now I get a mix of available and not available keys. Also the length of the result is below the number of rows the SQL Query finds in PHPMyAdmin.
Thanks in advance.
As the answer here states:
The equivalent of MySQL's NOW() is Doctrine DQL's CURRENT_TIMESTAMP().
CURRENT_DATE() only returns the date part.
This might explain, why the second approach did not give the same result as running a straight SQL query.
For the first approach you could try the following, even though I am not sure if it will make a difference:
->setParameter('date_now', new \DateTime())
Edit:
I found another potential problem in your QueryBuilder:
Instead of
->leftjoin('MyBundle:personToKey', 'ptk','WITH', 's.id = ptk.key')
you could try to write:
->leftjoin('k.personToKey', 'ptk')
The s.id was definitely wrong, not sure about the rest.
I finally found a working solution for my Problem, so I wanted to share it, if other People have a similar problem.
$now = new \DateTime() ;
$now1=$now->format('Y-m-d H:i:s');
$sql = 'SELECT * FROM key AS k
LEFT OUTER JOIN persontoKey AS ptk ON k.id = ptk.keyId
WHERE ( ptk.rueckgabe < :now ) ';
$em = $this->getDoctrine()->getManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->bindValue('now', $now1, \PDO::PARAM_STR);
$stmt->execute();
$helper= $stmt->fetchAll();

updating mysql table using php gives no change

I'm trying to update a mySQL table using php. Basically I pass an ordernumber (int) and use it to find both isbn and quantityordered which I then use to update another table.
$orderID=$_POST["order_ent_number"];
$query="select ISBN from Orders where orderNumber='$orderID'";
$isbn = mysql_query($query) or die(mysql_error());
$query="select quantityOrdered from Orders where orderNumber='$orderID'";
$quantityordered = mysql_query($query) or die(mysql_error());
$query="UPDATE Books SET inStock='$quantityordered' WHERE inStock='0' AND isbn='$isbn'";
$result = mysql_query($query) or die(mysql_error());
So using the MySQL bench, the query works (if I replace all variables with numbers) and changes it. The problem is when I use the variables in PHP, the code does not work. I tried the mysql_escape_string but that didnt work either. I checked the results of both variables $isbn and $quantityordered and they are right. I get no errors when I run it on the server but there is no change to inStock in the database. After searching around, someone said my variables need to be turned into integers? Not sure if this is correct or not but that is all I came up with. Any suggestions?
Actually you can do it in a single UPDATE statement by joining the tables,
UPDATE Books a
INNER JOIN Orders b
ON a.ISBN = b.ISBN
SET a.instock = a.quantityOrdered
WHERE a.instock = 0 AND
b.OrderNUmber = '$orderID' AND
a.ISBN = '$isbn'
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
maybe you can try
$query="select ISBN from Orders where orderNumber='".$orderID."'";
$query="select quantityOrdered from Orders where orderNumber='".$orderID."'";
$query="UPDATE Books SET inStock='".$quantityordered."' WHERE inStock='0' AND isbn='".$isbn."'";