I would like to know how can I execute a query, inside a phalcon controller, using parameters.
My SQL Query:
SELECT a.*, getApplicationData(a.id) as json_data
FROM application a
INNER JOIN application_data d on d.application_id = a.id
WHERE a.form_id=1
AND d.firstname LIKE '%:searchQuery:%' ;
Here is how I'm trying to execute (I found it in Phalcon's doc, but the example was not inside a controller).
$applications = $this->db->query(
$sqlQuery,
array('searchQuery'=>$searchQuery)
)->fetchAll();
I know that since you have the ORM I shouldn't be querying the DB like this, but for the feature I'm working on it has to be like this, this query is dymanic.
My question is how to pass the parameter for the :searchQuery: in the query.
Thanks in advance for any help.
You almost got it right. You only had to add the percents (%) in the bind array.
$sqlQuery = 'SELECT * FROM events WHERE title LIKE :searchQuery';
$applications = $this->db->query(
$sqlQuery,
array('searchQuery'=> '%' . $searchQuery . '%')
)->fetchAll();
Also notice how I binded the :searchQuery in the $sqlQuery. It only uses single : instead of surrounding the parameter. This is because Raw queries use directly the DB connection in our case it is PDO.
More examples can be found here: https://docs.phalconphp.com/en/latest/api/Phalcon_Db_Adapter_Pdo.html
Related
Is it possible in Laravel, using eloquent to get the raw SQL query generated by the ORM query ?
Also, is it possible to get an array of all the columns involved in that query ?
Consider for exemple that Eloquent query:
$query = Category::join('posts', 'post.category_id', '=', 'category.id');
Would it be possible to retrieve in the code, the raw SQL of that query, and most importantly, an array of the columns involved ? In this cas, the columns of the Category and the Post models (category.id, category.name, post.id, post.title, post.category_id, etc...)
You can enable ORM logging with:
DB::enableQueryLog();
// query
and when your query executed you can get it with:
DB::getQueryLog();
You can use toSql() and getBindings() and for query builder same as:
$sql = $query->toSql();
$bindings = $query->getBindings();
If you do not provide any fields it will default to *
I'm unsure what whereRaw is in PHP Laravel framework. Could you provide good and easily understandable example, please?
WhereRaw() is a function of Laravel query builder which puts your input as it is in the SQL query's where clause.
Think of it as the where() function whose input argument will not be processed before inserting into queries.
See the example below:
$Query = DB::table('some_table')->where('YEAR(date)', 'YEAR(CURRENT_DATE)');
In this Laravel will resolve your arguments to build a query. Which will result in the following query because your input will be treated as some field and its its value :
SELECT * FROM `some_table` WHERE `YEAR(date)` = `YEAR(CURRENT_DATE)`
Which is not desired.
And now if you use whereRaw like:
$Query = DB::table('some_table')->whereRaw('YEAR(date) = YEAR(CURRENT_DATE)');
Now Laravel put this where clause as it is in your query, like below:
SELECT * FROM `some_table` WHERE YEAR(date) = YEAR(CURRENT_DATE)
Hope it helped (:
WhereRaw: Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings.
If you are unable to generate the query you need via the fluent interface, feel free to use whereRaw()
Ex:
$users = User::whereRaw('age > ? and votes = 100', array(25))->get();
which is equals to:
"SELECT * FROM users WHERE age > 25 AND votes = 100";
Reference
In laraval we use query builder. But Sometime you need to execute raw sql query.
So you can inject it to whereRaw as this example :
whereRAW('YEAR(event_datetime) =?', [$year])
I'm trying to run a raw SQL query, inside a Controller class, and I'm having trouble to figure out why I can't bind more than one parameter. Take a look at the snippet below:
$sql = "select
u.id,
u.name,
u.email,
r.name as role
from user u
inner join role r on r.id = u.role_id
left join user_group_user ugu on ugu.user_id = u.id and ugu.user_group_id = ".$user_group_id."
where (u.name like :search or u.email like :search or r.name like :search)
and ugu.user_id is null and u.id not in( :notIn )
order by u.name, r.name";
$users = $this->db->query($sql, ['search' => '%'.$search.'%', 'notIn'=>$notInStr ])->fetchAll();
The $notIn variable has a value like 1,2,3. If I do the same thing only with the parameter :search the query works. When I try with both parameters (:search and :notIn) the query returns but the :notIn seems to not have effect in the query. It looks like it is not being bound.
How can I run this query considering both parameters?
Thanks for any help
UPDATE:
The binding is actually working but it is binding the :notIn as a string, so the executed query is .... not in ('1,2,3')
I have solved my problem just making sure that everything is a number and just concatenating in the query: ...u.id not in( ".$notInStr." )
Standard pdo library which phalcon is using and which phalcon db is wrapping doesn't accept array as bound parameter. You would need to use phalcon models.
Make use of Phalcon\Mvc\Model\Query\Builder. There is a inWhere method, that accepts array as parameter.
Remember to never use not filtered data that You get from end-user, like You just did. This makes Yours application vulnerable to SQLInjection attacks.
Ok, so I'm needing to create a query below in eloquent or Laravel in some matter. I'm just not sure how I would create something like this:
select * from
(select * from Bulk
where Login = 'moga' and ApptDate='2015-02-25'
order by FormatTime asc) as A
group by Name
This query will run just fine as a raw query in the database, I'm just not sure how I would pull this query off using query helper or eloquent.
You can use either Eloquent or Query Builder. Here's an example with the Query Builder:
DB::table(DB::raw('(select * from Bulk where Login = "moga" and ApptDate="2015-02-25" order by FormatTime asc) as A'))
->groupBy('Name')
->get();
With Eloquent you'd use ModelName::from() instead of DB::table(). But keeping in mind that DB::raw does not escape variable values inserted into the query string, you could build the nested query using the builder as well, to make sure you're not vulnerable to SQL injection:
$from = DB::table('Bulk')
->where('Login', $login)
->where('ApptDate', $date)
->orderBy('FormatTime')
->toSql();
DB::table(DB::raw('(' . $from . ') A'))->groupBy('Name')->toSql();
In the docs,
$results = DB::select('select * from users where id = ?', array(1));
The Problem
I have a variable $column and $value and I want them to search the database based on what column like this:
$results = DB::select('select * from users where ? LIKE "%?%"', array($column, $value));
But this throws an error:
SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $2 (SQL: SELECT * FROM test WHERE refno LIKE '%te%')
I tried hard-coding the value like this:
$results = DB::select('select * from users where ? LIKE "%te%"', array($column));
but it returns a blank array.
How do I do this? Please help.
EDIT:
The query is actually long (with multiple joins). So I prefer not to use the Query Builder style if possible. But if it's not possible, then I will just use Query Builder.
Info:
Laravel v4.2
PostgreSQL
It could be done in more Query Builder style, like that:
$results = DB::table('users')
->where($column, 'LIKE', '%' . $value . '%')
->get();
EDIT
The only reliable way how to do it with DB::select() is:
$results = DB::select("select * from users where ? LIKE '%?%'", array($column, $value));
It produces the right query, I checked it against the database, but also a blank array, or wrong results. Even if this method somehow worked, you still have to escape table and columns names manually, which is tedious and apparently does not work with ?. If you lets say had a $column named values this method would break, since values is a reserved word (at least in MySQL).
The Query Builder method is highly advised, because it also automatically adds SQL escapes to table and column names. Also it is is more portable across DB drivers. It also supports joins with ease. No need to use the method you wants.
the only way i find working
$phone = '%'.$phone.'%';
$seachbyphone = DB::select('SELECT * FROM user WHERE phoneno LIKE ?',[$phone]);
try this:
use App\User; //don't forget add this to header
$result = User::where('columnName', 'LIKE', "%$value%")->get();
LIKE '%?%'" is incorrect. It must be ? only as sql query only expects ? =>vacancy/placeholder for value. Not any single comma or wildcard.
So You need to add % sign with value not with ? =>(placeholder), and its safe as well.
That's why we need
$results = DB::select("select * from users where ? LIKE ?, [$column, '%'.$value.'%'.]);
I would not recommend DB::select() to anyone, even though you have perfectly valid SQL that works directly in the database engine Laravel produces peculiar errors with made-up error descriptions. Instead use DB::table('my_table')->select('...') instead.