MySQL PDO has no errors, but not pulling data - mysql

Something funky is going on with my MySQL PDO query.
If I pass in an array of values, it does not.
If I don't pass in the arrays it works.
I know this because I get a PDO error 0000, but when I run
$num_events_months = $result_events_months->rowCount();
it only returns a value if the values are hard-coded into the query.
I'm just not sure what I'm doing wrong?
The following DOES NOT work:
$query_events_months = "SELECT DATE_FORMAT(event_date, '%Y-%m') AS event_month_year, DATE_FORMAT(event_date, '%M') AS event_month_name FROM Events WHERE event_date >= :current_date AND status = :status GROUP BY event_month_year";
$result_events_months = $conn->prepare($query_events_months);
$result_events_months->execute(array(':current_date'=>'2014-10-01',':status'=>'published'));
The following DOES work:
$query_events_months = "SELECT DATE_FORMAT(event_date, '%Y-%m') AS event_month_year, DATE_FORMAT(event_date, '%M') AS event_month_name FROM Events WHERE event_date >= '2014-10-01' AND status = 'published' GROUP BY event_month_year";
$result_events_months = $conn->prepare($query_events_months);
$result_events_months->execute(array(':current_date'=>'2014-10-01',
':status'=>'published'));
I'm just not sure what I'm doing wrong?

PDO ERROR 000 is the value returned when a query executed successfully.
You should only print when it fails, otherwise you should ignore.
In your case something along the lines:
if(!$result_events_months->execute(array(...))){
var_dump($result_events_months->errorInfo()); //not outside of the failure block
}else{
var_dump($result_events_months->fetchAll());
}

Related

Quoting of Queries in perls mojolicious

I have a mojolicious app where I am using lots of queries, which are hard coded, so I am trying to differentiate between code and query by having new .sql files for each query.
I have some problems with the following query:
my $sql = $self->db->query(qq(
select
a,
b,
c
from
table
where
date_format(d, "%m") >= $month
and
date_format(d, "%m") <= $month
and
date_format(d, "%Y") >= $year
and
date_format(d, "%Y") <= $year
and
if(? = "", a, a=?)
), $a, $a);
The query above work perfect, but when I try to read it from a file my result is null.
my $path = Mojo::File->new('/path/to/file')->slurp;
my $sql = $self->db->query($path, $month,$month, $year, $year, $a, $a);
It doesn't matter if I use double quotes, single quotes or each perl function of quoting, the result is always null. When I get my params with $sth->{ParamValues} I get the right params for each call.
After coupule of hours of debugging and testing, I found out that the problem lies on the sql function "date_format" which is not called properly, but I couldn't find out why not. An alternative could be to format the time inside perl, but is not a beautiful way to handle that. I also tried to use sql variables for setting the params.
My sql file looks like:
select
a,
b,
c
from
table
where
date_format(d, "%m") >= ?
and
date_format(d, "%m") <= ?
and
date_format(d, "%Y") >= ?
and
date_format(d, "%Y") <= ?
and
if(? = "", a, a=?)
The solution was to use the interval function of mysql which is smart enough to calculate the date.
For the parameters I used the sprintf function and used one variable instead of 2.
my $date = sprintf('%4d-%02d-01');
select sum(a), sum(b) from t1 where c between $date and $date + interval 1 month;

How to write the below eloquent query code using raw query in laravel?

My eloquent query:
$data = (new Model())->whereDate('start_date', '<=', Carbon::today())
->whereDate('end_date', '>=', Carbon::today())
->count();
The raw query I have tried:
$data = (new Model())->select(DB::raw("COUNT(id) as countData where date(start_date) <= NOW() and date(end_date) >= NOW()"))->get();
How can I write my eloquent query as raw query. The below raw query gives me syntax violation error;
This is because of how you are constructing your query. If you inspect the generated SQL statement you'll see that the SQL FROM clause is actually on the end of your statement and not at all where it should be.
You'll want to split your WHERE clauses out and use either where or whereRaw. For example:
$data = (new Model)->select(DB::raw('COUNT(id) as countData'))
->whereRaw('date("start_date") <= NOW() AND date("end_date") >= NOW()')
->get();
Your question was a little unclear but if you want to do what you did with eloquent in raw query, be noted that the select function of DB in raw by itself, so simply write your query inside select function:
$tableName = (new Model)->getTable();
$data = DB::select("
SELECT COUNT(`id`) as `countData` FROM `$tableName`
WHERE DATE(`start_date`) <= NOW() AND DATE(`end_date`) >= NOW()
")->first();
Alternatively you may use whereRaw function of your Model:
$data = Model::whereRaw(
"DATE(`start_date`) <= NOW() AND DATE(end_date) >= NOW()"
)->count();

Whats wrong with my code Laravel Callback function GroupBy Month

Im going to count my pallet_condition 0,1,2,3 and group it by month
but i always got an error like this please help whats wrong with my code.
something wrong with my date_format?
My Error
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'created_at' in group statement is ambiguous (SQL: select count(*) as aggregate from `liip_psrm` inner join `liip_psrm_items` on `liip_psrm`.`id` = `liip_psrm_items`.`psrm_items_id` where date(`liip_psrm_items`.`created_at`) >= 2018-10-09 and date(`liip_psrm_items`.`created_at`) <= 2019-01-31 and `liip_psrm`.`status` = 0 and `liip_psrm`.`customer_id` = 14 and `pallet_condition` = 0 group by WEEK(created_at) order by WEEK(created_at) asc)
My Callback function
$problem_condition_computations = function($condition) use ($psrm_maintenance, $start, $end, $customers){
return DB::table('liip_psrm')
->join('liip_psrm_items', 'liip_psrm.id', '=', 'liip_psrm_items.psrm_items_id')
->whereDate('liip_psrm_items.created_at', '>=', $start)
->whereDate('liip_psrm_items.created_at', '<=', $end)
->select(
DB::raw("DATE_FORMAT(liip_psrm_items.created_at, '%Y-%m-%d') AS dates
"))
->where('liip_psrm.status','=', 0)
->where('liip_psrm.customer_id','=',$customers)
->where('pallet_condition', $condition)
->groupBy('dates')
->count();
};
"dates" field you are using in groupBy is alias name, So it do not identifying it and not working as you are expecting.
Same as you used in Select
DB::raw("DATE_FORMAT(liip_psrm_items.created_at, '%Y-%m-%d') AS dates")
Put it in GroupBy
& It will work.
Hope, It will help, Let me know if you still find difficulties.

Create Doctrine query

I have a quiz application where played rounds are logged in UserPerformanceEntity. The corresponding MySQL table looks like:
UserPerformance
---------------
id (PK)
user
start_time
end_time
max_level
I want to display some statistics, like 'You performed better than x% of players'. To calculate the percent of players who performed worse than the current I want to execute the following MySQL query:
SELECT COUNT(DISTINCT `user`)
FROM `UserPerformance`
WHERE
(end_time IS NOT NULL
AND end_time NOT LIKE '0000-00-00 00:00:00')
AND `user` != :current_user
AND max_level < :current_level
ORDER BY max_level DESC
But I have no idea how to implement this with doctrine. How should my querybuilder look like?
try this
$query = $this->createQueryBuilder('u');
$query->select('COUNT(DISTINCT u.id) as usercount')
->where('u.end_time IS NOT NULL')
->andWhere('u.end_time NOT LIKE :end_time')
->andWhere('u.id != :current_userid')
->andWhere('u.max_level < :current_level')
->setParameter('end_time', '0000-00-00 00:00:00')
->setParameter('current_userid', $current_userid)
->setParameter('current_level', $current_level)
->setMaxResults(1);
$result = $query->getQuery()->getResult();
return $result[0]['usercount'] ;
The only change is, you need id from current user instead object
Additional information that a user can play many times, so user id is not unique, one user can have many records. This is my solution:
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$result = $qb->select('COUNT(DISTINCT p.user) AS usercount')
->from('LoginetFBappVagoBundle:UserPerformanceEntity', 'p')
->where(
$qb->expr()->andX(
$qb->expr()->isNotNull('p.endTime'),
$qb->expr()->neq('p.endTime', ':endTime')))
->andWhere($qb->expr()->neq('p.user', ':userId'))
->andWhere($qb->expr()->lt('p.maxLevel', ':maxLevel'))
->setParameter('endTime', '0000-00-00 00:00:00')
->setParameter('userId', $userid)
->setParameter('maxLevel', $level)
->getQuery()
->getResult();
I started from #Alexander Keil's answer, but I used expressions, and I figured out that there is no need to group the (end_time IS NOT NULL AND end_time NOT LIKE '0000-00-00 00:00:00') part. However if I pass '0000-00-00 00:00:00' in the expression instead setting as a parameter, I get an error. And at last I have to count the distinct users the get the correct result.

SQL Field Update Syntax Issues with complex selection logic

The query below works fine and is what I need.
I want to add a new keyword onto "Keywords" e.g.
UPDATE bugs SET bug.keywords = CONCAT(bug.keywords, ', Report:DevProcess')
However no matter where I place this in the logic below, I get a syntax error.
The web examples I have seen and in Stackoverflow are for simple
Update ... WHERE .... examples.
SET #StartDate = '2016-03-01';
SET #EndDate = '2016-03-31';
SELECT
bugs_activity.bug_id,
bug.status_whiteboard AS Whiteboard,
bug.keywords AS Keywords,
bug.bug_status,
bug.resolution,
SUM(CASE WHEN fd.name = 'bug_status' AND (bugs_activity.added = 'VERIFIED' OR bugs_activity.added = 'CLOSED') THEN 1 ELSE 0 END) AS ClosedCount,
MIN(CASE WHEN fd.name = 'bug_status' AND bugs_activity.added = 'VERIFIED' THEN bug_when ELSE NULL END) AS verifiedDate,
MIN(CASE WHEN fd.name = 'bug_status' AND bugs_activity.added = 'CLOSED' THEN bug_when ELSE NULL END) AS closedDate
FROM bugs_activity
INNER JOIN bugs bug
ON bugs_activity.bug_id = bug.bug_id
INNER JOIN fielddefs fd
ON bugs_activity.fieldid = fd.id
WHERE
(bugs_activity.bug_when BETWEEN '2015-09-01' AND #EndDate)
AND (Keywords LIKE '%Region:Europe%')
AND NOT (Keywords LIKE '%Report:DevProcess%')
GROUP BY bug_id
HAVING
ClosedCount > 0
AND (
(verifiedDate IS NOT NULL AND verifiedDate >= #StartDate)
OR (verifiedDate IS NULL AND (closedDate IS NOT NULL AND closedDate >= #StartDate))
)
Additional info from questions:
Linqpad SQL talking to MySQL DB
From linqpad - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE bugs SET bug.keywords = CONCAT(bug.keywords, ', Report:DevProcess')' at line 20
I removed GroupBy line, same error.
CONCAT is what a web search tells me How to prepend a string to a column value in MySQL?
In the selected "bugs" I want to "UPDATE bugs SET bug.keywords = CONCAT(bug.keywords, ', Report:DevProcess') "
Bugzilla has historically for a long time used multiple keywords. It is what it is whether good or bad.
== 31/05/2016 update ==
I simplified the query and got past the syntax error, however no update. I confirmed account had DB write access by using the read account which produced an access denied error.
-- this shows the one record
SELECT bug_id
FROM bugs
WHERE (bugs.bug_status = 'VERIFIED') AND (bugs.status_whiteboard LIKE '%Leiden%') and (bugs.keywords LIKE '%Region:Europe%') AND NOT (bugs.keywords LIKE '%Report:DevProcess%')
-- this runs without an error but shows no records updated
UPDATE bugs SET bugs.keywords = CONCAT(bugs.keywords, ', Report:DevProcess')
WHERE (bugs.bug_status = 'VERIFIED') AND (bugs.status_whiteboard LIKE '%Leiden%') and (bugs.keywords LIKE '%Region:Europe%') AND NOT (bugs.keywords LIKE '%Report:DevProcess%')
The simpler syntax does "work", i.e. no syntax error however the write did not work initially. This turned out to be because the keyword schema required the keyword to be pre-defined. Adding the keyword in resulting in the record being updated.
-- this runs without an error but shows no records updated
UPDATE bugs SET bugs.keywords = CONCAT(bugs.keywords, ', Report:DevProcess')
WHERE (bugs.bug_status = 'VERIFIED') AND (bugs.status_whiteboard LIKE '%Leiden%') and (bugs.keywords LIKE '%Region:Europe%') AND NOT (bugs.keywords LIKE '%Report:DevProcess%')