How to Fix WHERE Clause in Laravel - sql

I have an issue with Laravel Eloquent when using a WHERE clause.
Code
<?php
$locale = Session::get('locale');
$categories = Category::whereHas('translations', function ($query) use ($locale) {
$query->where('locale', $locale);
})->get();
Generated SQL
select * from `categories`
where exists (select * from `category_translations`
where `category_translations`.`category_id` = `categories`.`id`
and **`locale` = ?**)
It does not register the given value for locale.
I'm also getting the same issue if I put ->where('locale', 'en'), and even if I try a raw query instead of using Eloquent model.
Any help would be much appreciated, thanks.

Like SR_ wrote in the comment toSql() function doesn't return variable binding. If you would like to see how the real queries looks like you can install tools like Laravel Debugar: https://github.com/barryvdh/laravel-debugbar

Related

Laravel: toSql function not displaying query correctly

I am trying to diedump the query on my index screen using this line of code:
dd(DB::table('members')->where('name', '=', 'Tycho')->toSql());
Now the problem is that when I am displaying the query on my screen I get this:
"select * from `members` where `name` = ?"
My final goal of these lines of code is that I can save offline queries and execute them when the application is online. Unless someone has a solution for this, I'll have to save the queries in a database.
You are seeing the ? placeholders as Laravel uses Prepared Statements.
See Ijas Ameenudeen's answer on another SO question which details how to add a toRawSql() macro on the Eloquent builder which will replace the placeholders with the bindings that you supplied to the original query.
This is because you are using the toSql method, you can use the getBindings method to get the values / bindings.
oneliner:
$query = DB::table('members')->where('name', '=', 'Tycho')->toSql();
// will give the raw query with bindings.
$sqlWithBindings = str_replace_array('?', $query->getBindings(), $query->toSql());
You can try this:
DB::enableQueryLog();
DB::table('members')->where('name', '=', 'Tycho')->get();
echo "<pre>";
print_r(DB::getQueryLog());

Query Queried Table Laravel

I was wondering if we could query already queried table. Like this:
$results = Table::where('name','like', '%'.$request['name'].'%')->get();
$results = $results::where('surname', 'like', '%'.$request['surname'.'%'])->get();
I try to do something like this, because I have many options to query from table, and some of them may be empty. So in order not to check all possibilities, and writing different queries, it would be easier in this way. Thanks in advance
The $result variable is in fact a Laravel Collection, so you have a lot of option to work with a Collection including its own where() function.
Imho I will go with this code:
$query = Table::where('name','like', '%'.$request['name'].'%');
$results = $query->get();
$results2 = $query->where('surname', 'like', '%'.$request['surname'.'%'])->get();

Using built-in SQL functions with SequelizeJS

Can I make Sequelize JS to include combined field to the result set, to get results like for following query?
SELECT id, NOW()-timestamp as recordAge FROM myTable
I wouldn't use raw query for this task, prefer to resolve it with model paradigm.
As there was no answer but someone has starred my question I'm posting the answer I've found myself:
The solution is to use Sequelize.literal() function. As for example in the question, the answer is following:
options = {};
options.attributes = ['id', sequelize.literal('(NOW() - timestamp) as recordAge')];
MyTable.find(options).success(success);

orderby doesn't work in Laravel Eloquent advanced query

I'd like to sort my data by using orderby in Laravel Eloquent advanced query. Here is my code:
$users = User::where(function($query){
$query->orderBy('created_at', 'DESC');
})->get()->toArray();
var_dump($users);
But it doesn't work. Instead if I use orderby like this:
$users = User::orderBy('created_at', 'DESC')->get()->toArray();
var_dump($users);
It works.
Can anybody suggest how to make the orderby works for the advanced query? Thanks
I tried all sorts of different combinations and found the orderBy must be outside the query function (or maybe should be the last one?). Here is the code which is working:
$users = User::where(function($query){
// ......
})->orderBy('created_at', 'DESC')->get()->toArray();
var_dump($users);

How to use a dynamic parameter in a IN clause of a JPA named query?

my problem is about this kind of query :
select * from SOMETABLE where SOMEFIELD in ('STRING1','STRING2');
the previous code works fine within Sql Developer.
The same static query also works fine and returns me a few results;
Query nativeQuery = em.createNativeQuery(thePreviousQuery,new someResultSet());
return nativeQuery.getResultList();
But when I try to parameterize this, I encounter a problem.
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in (?selectedValues)";
Query nativeQuery = em.createNativeQuery(parameterizedQuery ,new someResultSet());
nativeQuery.setParameter("selectedValues","'STRING1','STRING2'");
return nativeQuery.getResultList();
I got no result (but no error in console).
And when I look at the log, I see such a thing :
select * from SOMETABLE where SOMEFIELD in (?)
bind => [STRING1,STRING2]
I also tried to use no quotes (with similar result), or non ordered parameter (:selectedValues), which leads to such an error :
SQL Error: Missing IN or OUT parameter at index:: 1
I enventually tried to had the parentheses set directly in the parameter, instead of the query, but this didn't work either...
I could build my query at runtime, to match the first (working) case, but I'd rather do it the proper way; thus, if anyone has an idea, I'll read them with great interest!
FYI :
JPA version 1.0
Oracle 11G
JPA support the use of a collection as a list literal parameter only in JPQL queries, not in native queries. Some JPA providers support it as a proprietary feature, but it's not part of the JPA specification (see https://stackoverflow.com/a/3145275/1285097).
Named parameters in native queries also aren't part of the JPA specification. Their behavior depends on the persistence provider and/or the JDBC driver.
Hibernate with the JDBC driver for Oracle support both of these features.
List<String> selectedValues = Arrays.asList("STRING1", "STRING2");
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in (:selectedValues)";
return em.createNativeQuery(parameterizedQuery)
.setParameter("selectedValues", selectedValues)
.getResultList();
Instead of:
nativeQuery.setParameter("selectedValues", params);
I had to use:
nativeQuery.setParameterList("selectedValues", params);
This worked for me in derby. parameter without "()".
List<String> selectedValues = Arrays.asList("STRING1", "STRING2");
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in
:selectedValues";
return em.createNativeQuery(parameterizedQuery)
.setParameter("selectedValues", selectedValues)
.getResultList();
Replace this:
nativeQuery.setParameter("selectedValues","'STRING1','STRING2'");
with
List<String> params;
nativeQuery.setParameter("selectedValues",params);
I also faced the same issue.
This is what I did:
List<String> sample = new ArrayList<String>();
sample.add("sample1");
sample.add("sample2");
And now you, can set the sample in params.