I'm having a little issue with getting an sql query to work in drupal 7.
Basically, I'd like to know if my drupal code for the db_api is correct for the SQL query that I expect it to generate.
Please see code below:
/*
SQL Query
Note: The the 'a' in '%a%', is just a sample of some text input by a user.
*/
SELECT u.uid, fn.field_first_name_value, ln.field_last_name_value
FROM role r
JOIN users_roles ur ON (r.rid = ur.rid)
JOIN users u ON (u.uid = ur.uid)
JOIN field_data_field_first_name fn ON (fn.entity_id = u.uid)
JOIN field_data_field_last_name ln ON (ln.entity_id = u.uid)
WHERE (fn.field_first_name_value LIKE '%a%' OR ln.field_last_name_value LIKE '%a')
AND r.name = 'custom_role'
LIMIT 0, 5
/*
DRUPAL 7 DB API CODE
*/
$name = $_POST['name'];
$res = db_select('role', 'r');
$res->join('users_roles', 'ur', 'ur.rid = r.rid');
$res->join('users', 'u', 'u.uid = ur.uid');
$res->join('field_data_field_first_name', 'fn', 'fn.entity_id = u.uid');
$res->join('field_data_field_last_name', 'ln', 'ln.entity_id = u.uid');
$res->fields('u', array('uid'));
$res->fields('fn', array('field_first_name_value'));
$res->fields('ln', array('field_last_name_value'));
$or = db_or()->condition('fn.field_first_name_value', '%'.db_like($name).'%', 'LIKE');
$or->condition('ln.field_first_name_value', '%'.db_like($name).'%', 'LIKE');
$res->condition($or)->condition('r.name', 'custom_role', '=');
$res->range(0,5);
$res->execute();
Also, if there is way that I can see the generated sql by the db api, that would be great for debugging.
Thanks.
I cannot execute it because i do not have the same tables like you but your generated query looks good.
SELECT u.uid AS uid, fn.field_first_name_value AS field_first_name_value, ln.field_last_name_value AS field_last_name_value
FROM
{role} r
INNER JOIN {users_roles} ur ON ur.rid = r.rid
INNER JOIN {users} u ON u.uid = ur.uid
INNER JOIN {field_data_field_first_name} fn ON fn.entity_id = u.uid
INNER JOIN {field_data_field_last_name} ln ON ln.entity_id = u.uid
WHERE ( (fn.field_first_name_value LIKE :db_condition_placeholder_0 ESCAPE '\\') OR (ln.field_first_name_value LIKE :db_condition_placeholder_1 ESCAPE '\\') )AND (r.name = :db_condition_placeholder_2)
LIMIT 5 OFFSET 0
If you want to print the query yourself you can use
print $res->__toString() . "\n\n";
var_export($res->getArguments());
Or
watchdog('MY_QUERY_DEBUG', $res->__toString(), $res->getArguments());
To add it to your watchdog log.
Related
I'm trying to figure out if it's possible to use a local varaible inside a mysql statement.
I've a statement that looks something like this (unrelated fields, joins and conditions have been filtered):
SELECT
m.id,
IF (!m.subscribers_only OR m.user_id = ? OR !ISNULL(mu.media_id) OR !ISNULL(us.user_id), 1, 0) AS has_access
FROM media m
LEFT JOIN media_user mu ON mu.user_id = ? AND m.id = mu.media_id
LEFT JOIN user_subscriptions us ON us.user_id = ? AND m.user_id = us.user_subscriber_to_id
All 3 variable is the same variable, so instead of having to bind the parameter 3 times, is it possible to set a local variable in the statement and only having to do 1 bind.
I've considered using SET #current_user = 1 and then using #current_user, but as I'm using PDO, it's not possible to run two statements in one query, and I'm worried how the interaction is when combined with a load balancer.
Edit to show how I'm printing #paramter_test:
SELECT
m.id,
#parameter_test,
IF (!m.subscribers_only OR m.user_id = #parameter_test OR !ISNULL(mu.media_id) OR !ISNULL(us.user_id), 1, 0) AS has_access
FROM media m
JOIN (SELECT #parameter_test:= 1) a
LEFT JOIN media_user mu ON mu.user_id = #parameter_test AND m.id = mu.media_id
LEFT JOIN user_subscriptions us ON us.user_id = #parameter_test AND m.user_id = us.user_subscriber_to_id
Try something like:
SELECT
m.id,
IF (!m.subscribers_only OR m.user_id = #parameter_test OR !ISNULL(mu.media_id) OR
!ISNULL(us.user_id), 1, 0) AS has_access
FROM media m
JOIN (SELECT #parameter_test:= 1) a
LEFT JOIN media_user mu ON mu.user_id = #parameter_test AND m.id = mu.media_id
LEFT JOIN user_subscriptions us ON us.user_id = #parameter_test AND m.user_id =
us.user_subscriber_to_id
You can always create a variable inside a sql statement as long as it's declared before it's use.
In this case you won't be using placeholder ? since those are replaced by parameter.
I want to view data from mysql in codeigniter based on user who is logged in
but I got an error "A Database Error Occurred". I think I wrote the wrong code
t.USER = $this->session->userdata('user_id');
Here's the code:
function get_rekomen()
{
$query = $this->db->query("SELECT
c.*,
t.produk_id,
t.id_transdet,
t.kategori_id,
t.total_qty,
t.USER
FROM
transaksi_detail AS t
LEFT JOIN
(
SELECT
g.id_produk,
p.slug_produk,
p.foto,
p.foto_type,
p.harga_diskon,
p.diskon,
p.harga_normal,
p.judul_produk,
g.kat_id,
k.judul_kategori
FROM
(
SELECT
MAX(m.id_produk) AS id_produk,
m.kat_id
FROM
produk AS m
GROUP BY
m.kat_id
)
AS g
INNER JOIN
produk AS p
ON p.id_produk = g.id_produk
LEFT JOIN
kategori AS k
ON k.id_kategori = g.kat_id
)
AS c
ON c.kat_id = t.kategori_id
WHERE
t.USER = $ this -> session -> userdata('user_id');
<<// i think here's the problem
ORDER BY
total_qty DESC limit 1")->result();
return $query;
}
and the question is what is the correct code?
Here's one solution, but first make sure on your controller the $this->load->library('session'); is loaded or you can just add in on autoload.php.
Also you must add parameter to your model that will handle the user_id in session, so for example here's your model looks like:
function get_rekomen($user_id) { ...your query here... }
Then on condition using the user_id will be
t.USER = $user_id;
So on your controller, you can call your model like:
$user_id = $this->session->userdata('user_id');
$this->ModelClass->get_rekomen($user_id);
Additional: On your login phase, if the user success from logging in, the you must set the user data on session such as this $this->session->set_userdata('user_data', $session_data);
Hope this helps!
Maybe you can use this. You need to define $user_id first before adding them to WHERE statement...
$user_id = $this->session->userdata('user_id');
$sql = "SELECT c.*, t.produk_id, t.id_transdet, t.kategori_id, t.total_qty, t.USER
FROM transaksi_detail AS t
LEFT JOIN(SELECT g.id_produk, p.slug_produk, p.foto, p.foto_type, p.harga_diskon, p.diskon, p.harga_normal, p.judul_produk, g.kat_id, k.judul_kategori
FROM(SELECT MAX(m.id_produk) AS id_produk, m.kat_id
FROM produk AS m
GROUP BY m.kat_id)
AS g
INNER JOIN produk AS p ON p.id_produk = g.id_produk
LEFT JOIN kategori AS k ON k.id_kategori = g.kat_id)
AS c ON c.kat_id = t.kategori_id
WHERE t.USER = '$user_id'
ORDER BY total_qty DESC limit 1";
$query = $this->db->query($sql);
return $query->result();
Hope this can help you...
I found this sentence in the code:
$dql
= <<<DQL
SELECT u FROM AppBundle:User u
JOIN u.Roles r
JOIN u.team t
WHERE u.id NOT IN (
SELECT user.id
FROM GameBundle:Goal g
JOIN g.user user
WHERE
g.objective = :objective
)
AND
r.profile = :sales_profile
AND
r.company = :company
AND
u.onlyStatus NOT IN (:status)
DQL;
I don't know how to works that query inside NOT IN sentence, help me please.
I need to know:
What return the query inside of NOT IN, (data types, so on...)
How to works a query inside of NOT IN (is posible ?)
SELECT u FROM AppBundle:User u
JOIN u.Roles r
JOIN u.team t
WHERE u.id NOT IN (
SELECT user.id
FROM GameBundle:Goal g
JOIN g.user user
WHERE
g.objective = :objective
)
this means take all the users that don't currently have 'objective' in the 'Goal' table.
Is this what you needed ?
Hello I want to bind this to one query with JOIN.
How does this work:
Db::bind("uid", strip_tags($userid));
DB::bind("user_id", strip_tags($refer));
Db::bind("points_earn", strip_tags($points_earn));
Db::bind("points_refer", strip_tags($points_refer));
Db::query("UPDATE referrals SET `points_earn` = :points_earn WHERE new_id = :uid");
Db::query("UPDATE users SET `points` = `points` + :points_refer WHERE id = :user_id");
What I think but not work.
Db::query("UPDATE referrals r JOIN users u ON r.user_id = u.id SET `r.points_earn` = :points_earn WHERE r.new_id = :uid AND `u.points` = `u.points` + :points_refer WHERE u.id = :user_id");
Have anyone a solution?
Your syntax is right, but the back ticks are wrong and each SELECT only has one WHERE:
UPDATE referrals r JOIN
users u
ON r.user_id = u.id
SET r.points_earn = :points_earn
WHERE r.new_id = :uid AND u.points = u.points + :points_refer AND
u.id = :user_id;
The problem with backticks is that the following are quite different:
`r.points_earn`
`r`.`points_earn`
The first refers to a column called "r.points_earn". The second refers to the "points_earn" column in "r". The backticks aren't necessary so you can just remove them.
I'm not sure why this isn't working. If I join either table separately, it comes back with the appropriate results, but when I try to join them both, I get 0 results. (car_id and boat_id are both primary keys on their tables.)
$query = "SELECT
*
FROM
posted c
JOIN posted_car e on c.car_id = e.car_id
JOIN posted_boat g on c.boat_id = g.boat_id
WHERE
c.posted = 'posted'
ORDER BY date DESC LIMIT 0, 30";
$resultBoth = mysql_query($query, $db) or die(mysql_error($db));
Might be worth noting that when I do
LEFT JOIN posted_car e on c.car_id = e.car_id
RIGHT JOIN posted_boat g on c.boat_id = g.boat_id
I get results as if I had only joined the posted_boat table. If anyone could point me in the right direction...it would be much appreciated.
you are using JOIN that might be a problem . you should use left outer join to get proper result . check following syntax :
$query = "SELECT *
FROM
posted c
left OUTER JOIN posted_car e on c.car_id = e.car_id
left OUTER JOIN posted_boat g on c.boat_id = g.boat_id
WHERE c.posted = 'posted'
ORDER BY date DESC LIMIT 0, 30";
$resultBoth = mysql_query($query, $db) or die(mysql_error($db));