How to customize error message on Symfony2 - many-to-many

I'm trying to use DQL to create a query between a ManyToMany relation, here a snippet of my code:
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery("SELECT * FROM TestGroupBundle:Question");
It's a really basic SQL line, but I always get this weird error:
[Syntax Error] line 0, col 7: Error: Expected IdentificationVariable | StateFieldPathExpression | AggregateExpression | "(" Subselect ")" | ScalarExpression, got '*'
500 Internal Server Error - QueryException
Can someone tell me what does it mean please and how to fix it ? Thanks

You're mixing up SQL and DQL. There's no "*" in DQL since you're working with your object model. The proper syntax would be "SELECT q FROM TestGroupBundle:Question q". The result is wrapped in \Doctrine\Common\Collections\ArrayCollection object. You can iterate over the object to get your results.
There's one important thing to keep in mind about DQL:
A common mistake for beginners is to mistake DQL for being just some form of SQL and therefore trying to use table names and column names or join arbitrary tables together in a query. You need to think about DQL as a query language for your object model, not for your relational schema.

Doctrine doesn't always parse namespace shortcuts correctly. Try using the full namespace instead of TestGroupBundle:Question

Related

Trouble with AND operator on Eloquent Raw query MySQL JSON

I am trying to figure out the correct syntax to add an AND operator to the following Eloquent Raw query in which I am querying a MySQL (5.7.9) table's JSON field. In doing so, I would like to be able to have case insensitivity capabilities.
After doing initial research as to how to achieve this, I have my code working in a basic way like this:
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?)', ["%{$user_name}%"])
But my goal is to add an AND operator to narrow down my results further with a non-JSON varchar column.
I have tried this (and other variations without success):
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?)', 'and user_type = admin', ["%{$user_name}%"])
Which gives me an error:
"Array to string conversion"
I have also tried:
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?) and user_type = admin', ["%{$user_name}%"])
Which give me the following error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_type' in 'where clause'"
Other similar variations that have not resulted in errors have yielded too many or too few results.
How can I successfully adjust my syntax to query an additional non-JSON field with the correct results? Also, is doing a raw query like this the most effective way to do so with Eloquent, MySQL (5.79) and Laravel 5.6?
Thank you for any and all help/direction offered! :)
I think you should do something like
$users = User::where(DB::raw('lower(info_json->"$.full_name")', 'like', DB::raw('lower(%{$user_name}%)'))
->where('user_type', '=', 'admin')
Probably I have some sintax error but main idea is to use DB::raw to help you with your query.
I figured it out. My syntax should have looked like this:
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?)', ["%{$user_name}%"])->where('user_type', '=', 'admin')->get();
Thanks to those who assisted with this! Like a lot of syntax/coding problems, taking a little break from it helped me to figure it out quite quickly when I returned to it.

Laravel: using WHERE CONCAT in query

I am pretty new to laravel and facing a problem building a query using CONCAT:
#From input
$password = $request->password;
#sql statement
UserMainTbl::where('username', '=', $username)->whereRaw('hashkey', '=', CONCAT('admin_id'.$password))
Table: UserMainTbl
Field: username, hashkey, admin_id
Got error:
Call to undefined function App\Http\Controllers\Auth\CONCAT()
------
Update:
I change my code and manage to stop the above error. But getting new error.
->where('hashkey', '=', DB::raw('concat(admin_id,"$password")'))
Column not found: 1054 Unknown column 'password123' in 'where clause' (SQL: select * from user_main_tbl where username = xxx and hashkey = concat(admin_id,password123) limit 1)
------
Update [Solve]:
My bad on this one. It is just a simple string. Here is the solution for future reference, if any. Lol:
->where('hashkey', '=', DB::raw('concat(admin_id,"'.$password.'")'))
Can someone help to point how can I do it right?
Many thanks.
I know you have solved the issue, but your solution can open up possibilities for SQL Injection if you don't escape the user input.
One way to tackle this is by adding a binding.
UserMainTbl::where('username', '=', $username)
->where('hashkey', '=',DB::raw('concat(admin_id,"?")'))
->addBinding($password);
https://laravel.com/docs/5.3/queries#raw-expressions
Always be careful in using RAW method in query builder since it's prone to SQL injections. I suggest to separate the concatenation of the "admin_id" and "password" and use the standard WHERE method to avoid the problem.

what is wrong with this line of SQL?

SELECT Batch.NumStud
FROM Batch
WHERE CourseID='$courseid'
INNER JOIN Course
ON Batch.CourseID=Course.CourseID"
an error that says mysql_fetch_array(): supplied argument is not a valid MySQL result resource in <b>F:\AppServ\www\anNoECourse.php
is shown.This code was written to feed in data to a google chart.
You put SQL in wrong order (JOIN and WHERE are switched):
SELECT Batch.NumStud
FROM Batch INNER JOIN Course
ON Batch.CourseID = Course.CourseID
WHERE Course.CourseID = '$courseid'
It seems, that your query can be simplified (check your data):
select Batch.NumStud
from Batch
where Batch.CourseID = '$courseid'
I think the error is a bit more complex. Due to the fact that your SQL is invalid, you're not getting a result set. This case is not handled correctly by your PHP code!
So in addition to correcting your SQL as the others have suggested, please make sure to handle the case where you get no results or your query results in an error correctly in your PHP code!
The second part to your solution is as follows:
$result = mysql_query(...);
if ($result)
{
while (...)
...
}
This makes sure that mysql_query actually returned a result set and not false, which it does in case of errors (due to your invalid SQL code, but also in other cases). So just fixing your SQL is not enough to make your script error proof.
But again, do no longer use the mysql_.... functions! They are deprecated.

how to use string left function in hql

I have a sql query like this
select column from table where path = left('INPUTSTRING', length(path));
and trying to accomplish it in hql like this,
return session.createQuery("from Table where Path = left(:input, length(Path))").
query.setParameter("input", inputPath).
.list();
and getting an error like this
Caused by: org.hibernate.hql.ast.QuerySyntaxException: unexpected token: left near line 1
how to get this done? What is the corresponding string function in hql? Is there a solution for this using criteria query apis?
Yes, left() is not supported by the MySQLDialect. See the list of HQL supported functions on API docs.
Now you have left with 2 options.
Use session.createSQLQuery() method.
Create Your own Dialect class by extending the MySQLDialect and register the function there. This is told at hibernate forum here explained well in a blog post here.
I'm not sure if HQL does this for you , but you can use IQuery/session.CreateSQLQuery() to use a raw SQL query to populate a mapped entity. I've never used it for substrings, but have used it for aggregate functions. Check chapter 13 of the NHibernate docs and see if that does it for you. You can check the query substitution available in Nhibernate - here

How To Use MATCH In Symfony2 Database Query

I'm building a search feature for my Symfony2 project, and I wrote the SQL for it as follows:
SELECT dlc.title, dlc.description, dlc.keywords
FROM ShoutMainBundle:Dlc dlc
WHERE MATCH (dlc.title, dlc.description, dlc.keywords) AGAINST (":keyword" IN BOOLEAN MODE)
AND dlc.type = (":audio")
ORDER BY dlc.date DESC
However, when I run this in the project the following error is given:
[Syntax Error] line 0, col 96: Error: Expected known function, got
'MATCH'
Is there an alternative I could use instead of MATCH? At the moment (just so I can do basic testing) I'm using LIKE, but it doesn't work too well if it's more than one word being used to search with.
EDIT:
This is how the code is used within the code:
$em = $this->getDoctrine()->getEntityManager();
$wckeyword = '%'.$skeyword.'%';
$dlcresult = $em->createQuery('
SELECT dlc.title, dlc.description, dlc.keywords
FROM ShoutMainBundle:Dlc dlc
WHERE MATCH (dlc.title, dlc.description, dlc.keywords) AGAINST (":keyword" IN BOOLEAN MODE)
AND dlc.type = (":audio")
ORDER BY dlc.date DESC'
)->setParameters(array('type' => $stype, 'keyword' => $wckeyword));
$dlcres = $dlcresult->getResult();
Doctrine doesn't support that out-of-the-box, true. But you can:
Create custom functions for DQL yourself
Use native SQL and custom hydration
This is not currently possible with Doctrine2 ORM. As Doctrine supports many different database vendors and most of them don't have a FULLTEXT search feature, it's not supported at all.
You can always use Doctrine2 DBAL for searching. You lose all these nifty orm features, but in my practice they aren't that needed in searching situations anyway.