Can select and from be parametrized in Doctrine's QueryBuilder? - mysql

According to Doctrine's documentation it is possible to bind parameters to a query. Example:
$qb->select('u')
->from('User u')
->where('u.id = ?1')
->orderBy('u.name', 'ASC')
->setParameter(1, 100);
Derived from this question I would like to know if it is possible to parametrize the select and the from statement as well? Like
$qb->select('?1')
->from('?2 u')
->where('u.id = 2')
->orderBy('u.name', 'ASC')
->setParameters(array(1 => 'mytable', 2 => 'mycolumn'));
I didn't manage to do so, but maybe I just did not know the proper way. Does anyone?

This is the way prepared statements work with PDO. The query and the statement are being send seperately. This allows your database to calculate the optimal query path for your query. The query path then makes use of the parameters to get the right results. The query path will try to optimize speed for the next time you make the same query. So for select and from you just have to do select($select). Note that the optimization will be lost of you put a new select each time.
Update:
This is a related answer: https://stackoverflow.com/a/182353/1833322
This is an example of how it should look in DQL:
$query = $em->createQuery('SELECT x FROM '.$mappingPlusEntity.' x WHERE x.id = ?1');
$query->setParameter(1, 321);

Related

Rewrite MYSQL query using Laravel query builder

I'm trying to rewrite MYSQL query using Laravel query builder
So this is the query
DB::select("SELECT * FROM accomodation WHERE id NOT IN
(SELECT accomodation_id FROM bookings
WHERE (`checkin` <= '$request->in' AND `checkout` >= '$request->out'));");
And this is what I've done so far
Accommodation::whereNotIN('id', function($q)
{
$q->select('accomodation_id')
->from('bookings')
->where('checkin', '<=', '$request->out')
->where ('checkout', '>=', '$request->in');
})
->get();
The problem is the first query is giving me expected results but the second one isn't
Can someone point out what I'm doing wrong?
I think you type it wrong. Look at the $request->in and $request->out. You may want to flip it. and why you use '$request->in' instead of $request->in. It will parse as string instead of the value
You don't have use. For example php Accommodation::whereNotIN('id', function($q) use ($request) and you need to flip condition with request ;)

Use "Query Builder" to create a function allowing to take the average of values - Symfony

I need help concerning the use of "Query Builder" in Symfony.
I would like to retrieve the values ​​of an attribute (Note) from one of my tables (Avis) in my database. After that, I would like to average all of his scores for display on my site.
For now I have the SQL query which achieves what I want :
SELECT AVG(avis.note) AS notetotal FROM avis
But afterwards, I don't understand what to do, or at least how "Query Builder" works
With the QueryBuilder you can build your queries step by step in a programmatically way, but its actualy only build the DQL wich you can get with $queryBuilder->getDql(). There are some cases where its easier to use the QueryBuilder instead of concatinate a long DQL query string.
There are two possible ways to build the query with the QueryBuilder. But for most cases its recommended to use plain DQL where ever you can, as its more readable.
First with the Expr Class
$queryBuilder = $this->getDoctrine()->getManager()->createQueryBuilder('a');
$queryBuilder->select($queryBuilder->expr()->avg('a.note'))
->from(Avis::class, 'a');
$avg = $queryBuilder->getQuery()->getSingleResult();
// $avg = [1 => (int) AVG]
or without Expr Class
$queryBuilder = $this->getDoctrine()->getManager()->createQueryBuilder('a');
$queryBuilder->select('AVG(a.note) as notetotal')
->from(Avis::class, 'a');
$avg = $queryBuilder->getQuery()->getSingleResult();
// $avg = ['notetotal' => (int) AVG]
The same in DQL
$dql = 'SELECT AVG(a.note) AS notetotal FROM ' . Avis::class . ' a';
$avg = $this->getDoctrine()->getManager()->createQuery($dql)->execute();
// $avg = [0 => ['notetotal' => (int) AVG]]

Use `AND` in Laravel Query Builder, syntax error (orOn)

I have this sql (MariaDB) query, it works ok:
SELECT
admin_combustibles.nombre,
admin_combustibles.id_combustible,
admin_combustible_unidades.nombre AS unidades,
admin_tipo_combustibles.nombre AS tipo_combustible,
admin_indice_combustibles.valor_combustible
FROM
admin_combustibles
INNER JOIN admin_combustible_unidades ON admin_combustibles.combustible_unidades_id = admin_combustible_unidades.id_combustible_unidad
INNER JOIN admin_tipo_combustibles ON admin_combustibles.tipo_combustible_id = admin_tipo_combustibles.id_tipo_combustible
LEFT JOIN admin_indice_combustibles ON admin_combustibles.id_combustible = admin_indice_combustibles.combustible_id
AND admin_indice_combustibles.anio = 1992
AND admin_indice_combustibles.mes = 6
ORDER BY
admin_combustibles.nombre
But when I try to make it through Laravel, I have some error because Laravel put some on the number 1992, in that way the query doesn't work.
Plus, I don't know how to do the AND on Laravel, I only have orOn but it doesn't work:
$datos = AdminCombustible::select([
'admin_combustibles.nombre',
'admin_combustibles.id_combustible',
'admin_combustible_unidades.nombre AS unidades',
'admin_tipo_combustibles.nombre AS tipo_combustible',
'admin_indice_combustibles.valor_combustible'])
->join('admin_combustible_unidades', 'admin_combustibles.combustible_unidades_id', '=', 'admin_combustible_unidades.id_combustible_unidad')
->join('admin_tipo_combustibles', 'admin_combustibles.tipo_combustible_id', '=', 'admin_tipo_combustibles.id_tipo_combustible')
->leftJoin('admin_indice_combustibles', function ($join) {
$join->on('admin_indice_combustibles.combustible_id', '=', 'admin_combustibles.id_combustible')->orOn('admin_indice_combustibles.anio', '=', 1992);
})
->get();
dd($datos);
I got an sql syntax error.
Any help on how to make that query with query builder of Laravel? (I put the entire query as DB::raw and it works, but I don't want to use raw() )
I think there might be two problems here. Since you are using and in your original query, you might be needing to use or instead of orOn on your join.
Also you will need to use DB::raw() on the parameters, otherwise Laravel will consider them columns....
$join->on('admin_indice_combustibles.combustible_id', '=', 'admin_combustibles.id_combustible')->on('admin_indice_combustibles.anio', '=', DB::raw('1992'));

Codeigniter, Active Record doesn't accept WEEK parameter

It seems that Active Record (Codeigniter) doesn't accept the WEEK parameter and I don't understand why?!
Whern i remove '3', my query works properly!
$this->db->select('WEEK(insere_le,3) AS semaine, COUNT(*) AS nombre')
->from($this->table_name)
->where(array(
'type_anomalie' => "Dérogation",
'YEAR(insere_le)' => $year
))
->group_by('WEEK(insere_le,3)')
->get()
->result_array();
This query, shows the following string when I execute it:
SELECT WEEK(insere_le, `3)` AS semaine, COUNT(*) AS nombre FROM (`aero_anomalie_montage`) WHERE `type_anomalie` = 'Dérogation' AND YEAR(insere_le) = '2014' GROUP BY WEEK(insere_le, `3)`
As you can see it adds an apostrophe before the number 3 and after the parenthesis )
It looks a little confused by your syntax. Why not put them in two different selects (if that's possible...)?
I don't know if this will help, but I found this, it will prevent it from adding the backticks altogether.
$this->db->select() accepts an optional second parameter. If you set
it to FALSE, CodeIgniter will not try to protect your field or table
names with backticks. This is useful if you need a compound select
statement.
http://ellislab.com/codeigniter/user-guide/database/active_record.html
hmm, if you look at active rec class (system/core/database/DB_active_rec.php) you will find this in function select() :
if (is_string($select))
{
$select = explode(',', $select);
}
so what you're select is doing is actually exploding your string into an array like this:
array(
WEEK(insere_le,
3) AS semaine,
COUNT(*) AS nombre
);
and then processing this.
This looks like an oversight from the developers of the active record class, and probably won't be solved by not escaping the values...
On the other hand, it actually checks its a string prior to the above.. so could try this:
$this->db->select(array('WEEK(insere_le,3) AS semaine', 'COUNT(*) AS nombre'))...
and the same with group_by(array('WEEK(insere_le,3)'))...
so end result would be:
$this->db->select(array('WEEK(insere_le,3) AS semaine', 'COUNT(*) AS nombre'))
->from($this->table_name)
->where(array(
'type_anomalie' => "Dérogation",
'YEAR(insere_le)' => $year
))
->group_by(array('WEEK(insere_le,3)'))
->get()
->result_array();
you tried this?:
$this->db->select("WEEK(insere_le,3) AS semaine, COUNT(*) AS nombre", FALSE);

Codeigniter mysql where not equal to query

Mysql codeigniter query is not working properly.
Suppose if mysql table looks like this:
user_id|user_name
1|john
2|alex
3|sam
Here user_name is unique
The following query should return false if user_name=john and user_id=1 and true if say user_name=john and user_id=2.
$this->db->get_where('user', array('user_name' => $name,'user_id !=' => $userid));
But it returns true in the case user_name=john and user_id=1.
Can anyone suggest me an alternative way of querying not equal to.
print($this->db->last_query()) gives:
SELECT * FROM (user) WHERE user_name = 'john' AND user_id != '1'
Why dont you use simple $this->db->query('your query');
Simply try this, Add the desired condition in the where function.
$this -> db -> where('invitee_phone !=', $user_phone);
You can go follwoing way too. It work for me
$total = 5;
$CI = get_instance();
$CI->load->database();
$CI->db->order_by('id','asc');
$topusers = $CI->db->get_where('users',array('user_type != 1 && `status` =' => 1),$total,0);
echo $CI ->db ->last_query();
die;
and if still not work for you can go with #rohit suggest: $this->db->query('your query');
Type 1:
Using ->where("column_name !=",$columnname) is fine for one column.
But if you want to check multi columns, you have to form an array inside where clause.
Like this
$whereArray = array(
"employee_name" => $name,
"employee_id !=" => $id,
);
$this->db->select('*')->from('employee')->where($whereArray);
Type 2:
We can just write exactly what we want inside where.
Like
$thi->db->where(("employee_id =1 AND employee name != 'Gopi') OR designation_name='leader#gopis clan'");
Type 2 is good for working with combining queries, i mean paranthesis "()"
you can follow this code:
$query = $this->db->select('*')->from('employee')->where('user_name', $name)->where('user_id !=', $userid)->get();
$last_query = $this->db->last_query();
$result = $query->result_array();
if you pass $name = 'john' and $userid = '1' then it return empty array.
The problem with using $this->db->query('your query'); is that it is not portable. One of the most important reasons to embrace the query builder methods is so that no matter what database driver you use, CodeIgniter ensures that the syntax is appropriate.
If a bit of discussion was possible, I'd probably like to hear why you need composite primary identifiers in your table and I'd like to see what your table schema looks like. However, I think the time for discussion has long passed.
Effectively, you want to return a boolean result stating the availability of the combination of the username AND the id -- if one is matched, but not both, then true (available).
To achieve this, you will want to search the table for an exact matching row with both qualifying conditions, count the rows, convert that integer to a boolean, then return the opposite value (the syntax is simpler than the explanation).
Consider this clean, direct, and portable one-liner.
return !$this->db->where(['user_name' => $name,'user_id' => $userid])->count_all_results('user');
this will return false if the count is > 0 and true if the count is 0.