Codeigniter mysql query AND_OR - php

Just trying to write custom string for $this->db->where(); function but I get syntax errors. Could you have a look on the code below to find the mistake
$where = "'phone' => $this->input->post('phone') AND '2g' = $data['2g'] OR '3g' = $data['3g'] OR '4g' = $data['4g']";

You're mixing two types of parameters for the $this->db->where() function.
From the docs
http://ellislab.com/codeigniter/user-guide/database/active_record.html
You either supply an associative array (like 'phone' => $this->input->post('phone'))
or you suppliy a custom string $where = "name='Joe' AND status='boss' OR status='active'";
You can't mix the two

Related

How to correctly use multiple SqlSelect set/add where functions

I'm piecing together an SQL query using SilverStripes SQLSelect class with some optional (frontend) filters.
When attempting to use addWhere() with parameters the query has no results. E.g:
$sql->useConjunction();
$sql->addWhere(['SiteTree.ClassName' => 'ResourcePage']);
if (self::$Filters['Tags'])
{
$sql->addLeftJoin('ResourcePage_Tags', 'ResourcePage_Tags.ResourcePageID = SiteTree.ID');
$sql->addWhere(['ResourcePage_Tags.ResourceTagID IN (?)' => implode(',', self::$Filters['Tags'])]);
}
if (self::$Filters['Types'])
{
$sql->addLeftJoin('ResourcePage_Types', 'ResourcePage_Types.ResourcePageID = SiteTree.ID');
$sql->addWhere(['ResourcePage_Types.ResourceTypeID IN (?)' => implode(',', self::$Filters['Types'])]);
}
If I treat it as a string, I do get the results (like I expect testing with manual SQL). E.g:
$sql->useConjunction();
$sql->addWhere("SiteTree.ClassName = 'ResourcePage'");
if (self::$Filters['Tags'])
{
$sql->addLeftJoin('ResourcePage_Tags', 'ResourcePage_Tags.ResourcePageID = SiteTree.ID');
$sql->addWhere('ResourcePage_Tags.ResourceTagID IN ('.implode(',', self::$Filters['Tags']).')');
}
if (self::$Filters['Types'])
{
$sql->addLeftJoin('ResourcePage_Types', 'ResourcePage_Types.ResourcePageID = SiteTree.ID');
$sql->addWhere('ResourcePage_Types.ResourceTypeID IN ('.implode(',', self::$Filters['Types']).')');
}
The generated (simplified) query found using $sql->__toString() is:
SELECT
DISTINCT SiteTree.*
FROM
SiteTree
LEFT JOIN
"ResourcePage_Tags" ON ResourcePage_Tags.ResourcePageID = SiteTree.ID
LEFT JOIN
"ResourcePage_Types" ON ResourcePage_Types.ResourcePageID = SiteTree.ID
WHERE
(SiteTree.ClassName = ?)
AND (ResourcePage_Tags.ResourceTagID IN (?))
AND (ResourcePage_Types.ResourceTypeID IN (?))
The parameters portion of the above output is an array:
'ResourcePage',
1 => '38'
2 => '5,4'
The omitted parts of the query is some MATCH AGAINST and LIMIT ORDER BY clauses that are always there.
What have I done wrong to get two different behaviours between string and the parameterised version?
The first example you had which was using in (?) and then passing an array of values will not execute correctly because the assumption is that ? is one value when using the prepare. Which means you are now querying for one ResourceTypeID that is equal to array_value1,array_value2. You therefore need to have a placeholder (?) per item in the self::$Filters['Tags'] array.
The framework does have a helper method to achieve this like so:
$placeholders = DB::placeholders(self::$Filters['Tags'])
$query->addWhere([
"ResourcePage_Types.ResourceTypeID IN ($placeholders)" => self::$Filters['Tags']
]);

How to search for 2 values in the same field with codeigniter?

I have a database field containing keyword ids ["1","2","3","4","5","6"] and I want to search for several of these ids in the same field.
Here is the idea of what I would like to achieve:
$tags[] = "\"1\"";
$tags[] = "\"2\"";
$query = $this->db->like(array('ids_keywords' => $tags[0], 'ids_keywords' => $tags[1]));
The problem here is that codeigniter only executes the last request instead of both because the search field is same.
What would be the best solution to do this?
try the following
$arrTags = [1,2];
$this->db->group_start()
foreach($arrTags AS $strTag)
{
$this->db->like(ids_keywords, '"'.$strTag.'"');
}
$this->db->group_end();
You can write your own clauses:
$where = "ids_keywords='1' AND ids_keywords='2' OR ids_keywords='3'";
$this->db->where($where);
For safe query use question mark(?)
$sql = "SELECT * FROM some_table WHERE ids_keywords = ? AND ids_keywords = ? AND ids_keywords = ?";
$this->db->query($sql, array(1, 2, 3));
In the above example, the question mark(?) will be replaced by the array in the second parameter of query() function. The main advantage of building query this way is that the values are automatically escaped which produce safe queries. CodeIgniter engine does it for you automatically.

Dynamically creating OR conditions by passing an array to a query in MySQL PHP

I am trying to create OR condition dynamically using an array. Given an array, of course names $courses = array('Eng, 'Deu', 'Bio', 'Chemi') I want to have a SQL query that uses the values of the array in its AND clause with OR conditions like:
SELECT *
FROM classe
/* The OR conditions should be created in AND clause using array */
WHERE class = 'EFG' AND (course = 'Eng' OR course = 'Deu' OR course = 'Bio')
I trying to do it in PHP MySQL.
Any help would be really appreciated.
Thanks in Advance.
Instead of so many OR clauses, you can simply use IN(..):
SELECT *
FROM classe
WHERE class = 'EFG' AND course IN ('Eng' ,'Deu', 'Bio')
In the PHP code, you can use implode() function to convert the array into a comma separated string, and use it in the query string generation.
The IN clause will be easier to use than ORs. If you are using PDO you can take advantage of its execute binding and build the placeholders dynamically then just pass your array to it.
$courses = array('Eng', 'Deu', 'Bio', 'Chemi');
$placeholders = rtrim(str_repeat('?, ', count($courses)), ', ');
$query = "select * from table WHERE class = 'EFG' AND course in ({$placeholders})";
$stmt = $pdo->prepare($query);
$stmt->execute($courses);
Demo: https://3v4l.org/jcFSv (PDO bit non functional)

update query with functions in typo3

I'm trying to use the typo3 update function with the mysql CONCAT function. Can you tell me how to manage that? What I tried:
$updateArray = array("field" => 'CONCAT( field'.','.$toAppend.')');
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('table','id = '.'"'.$some_id.'"',$updateArray);
That does not work, because that query is executed:
UPDATE table
SET
pagesEdited='CONCAT( field,'value')'
WHERE
id = "id"
As you see, the concat function is escaped.
The reference documentation isn't very clear about it, however, just appending TRUE to your parameters of the update function should disable quoting:
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('table','id = '.'"'.$some_id.'"',$updateArray, TRUE);
That also means that you will have to do your own input sanitization before lauching the query, if you haven't already:
$toAppend = $GLOBALS['TYPO3_DB']->fullQuoteString($toAppend, "");
Have a look at the noQuote parameter of the fullQuoteArray() method of TYPO3\CMS\Core\Database\DatabaseConnection that is used by exec_UPDATEquery():
#param boolean|array $noQuote List/array of keys NOT to quote (eg. SQL functions) - ONLY for associative arrays
And when you take a kloser look ath this method, you will see that a simple true does not do the trick as expected. Simply use a list of fields (comma separated list) or an array to let TYPO3 know which fields should not be escaped.
In your case it would look like this:
$updateArray = array(
'field' => 'CONCAT(field,' . $GLOBALS['TYPO3_DB']->fullQuoteString($toAppend, 'table') . ')',
);
$where = 'id = ' . $GLOBALS['TYPO3_DB']->fullQuoteString($some_id, 'table');
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('table', $where, $updateArray, 'field');

get_where with md5()

I want to perform this simple query using Codeigniter:
$user = $this->db->get_where($type,array("id"=>$id));
$type is the name of the table and
$id is a md5() value so I want to do something like $this->db->get_where($type,array(md5("id")=>$id)); that of course is not possible to do.
the answer could be $this->db->query('select * from $type where MD5(id) = $id'); but I would prefer a more compact way like get_where() to perform query.
any suggestions?
$this->db->where('MD5(id)', $id, FALSE);
The 3rd argument when set to FALSE will stop CI from protecting your field and table names with backticks so instead of turning the code into:
WHERE `MD5(id)` = 'THE ID'
it will be:
WHERE MD5(id) = 'THE ID'
$this->db->get_where($type,array("md5(id)"=>$id)); works perfectly. I get the record I want.
To answer the original question which I came across recently and found this as the top result in Google.
$user = $this->db->get_where( $type, array( 'md5( id ) =' => $id ) );
You can also substitute = for other operators such as LIKE and NOT LIKE.

Categories