Error when using selectRaw() Laravel method with parameter binding - php

I'm trying to run this: $query->selectRaw('count(?)', [$column]) on Laravel 7.0, but gives me an error:
SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $1.
PS: $column is a string.
When I put count(distinct ?), it results in wrong count.
I already tried "{$column}" and '%'.$column.'%', but it didn't work.

I tried other ways for hours, until I ask in a community and someone answered me that it's not possible to do this. The binding will only works with column values or something like that, despite that it doesn't have detailed uses of the selectRaw method.
Well, I've lost many hours, so I gave up and went to my objective with another approach.

You can use param in selectRaw by using quotes
Example:
$column = 1;
$query->selectRaw('count(**$column**)');

Related

Select month from a date field in laravel

I'm trying to perform a query in Laravel 7 that gets the month part of a date field. I tried the following queries
$test = MyModal::selectRaw('month("date_col") as temp')->get();
$test = MyModal::select(DB::Raw('month("date_col") as temp'))->get();
$test = DB::table('my_table')->select('month("date_col") as temp')->get();
All variation of the same query. If I dump the query log, the query is correct for all 3
select month("date_col") as temp from "my_table"
If I run this on my DB I get the result as well. But I keep getting this error in laravel:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such function: month (SQL: select month("date_col") as temp from "my_table")
Am I doing something wrong? And is there a way to do this query in laravel?
Edit: Sorry forgot to mention this is with Laravel's unit testing
I think the problem in the way you use Month function
you don't set quotations for the column name, it should be:
$test = MyModal::selectRaw('month(date_col) as temp')->get();
it should work
You can do something like this:
MyModal::select(DB::raw("MONTH(date_col) month"))->get();
Thanks to OMR's comment this solution finally worked
$test = MyModel::selectRaw('strftime("%m", "date_col") as temp')->get();
Update: It looks like what I had in the beginning worked fine and the unit test was the only part throwing this error. Since I was working with mysql while the test environment was using sqlite which apparently doesnt like the "month()" function which OMR did point out in his comment. So this solution works in the test but not in live. Couldn't figure out how to change the test environment to use in memory mysql instead of sqlite. If anyone knows how to please add an answer here.

PHP Atlas.ORM returns always the same result

I want to load data from a SQLite database in PHP using Atlas.Orm.
When I run the following snippet, I get a set of 1773 results, but each result is the same!
$atlas = Atlas::new('sqlite:[Path To Database]');
$result = $atlas->select(Stop::class)->fetchRecords();
Can anyone tell me whats wrong here?
After several hours of desperation, I found the issue by myself. The ORM needs the PRIMARY_KEY constant in the corresponding *Table class to be set, otherwise fetching records will fail like this.

Laravel Fluent Query Builder Update Query

I want to add two columns while using update, like this:
Update purchase_stock inner join stock on purchase_stock.fkstockid=stock.stockid SET currentavailable=currentavailable+subquantity where fkorderid='1';
Here is the current Fluent code:
DB::table('purchase_stock')->join('stock','stock.stockid','=','purchase_stock.fkstockid')->where('fkorderid',$orderId)->update(array('currentavailable'=>'currentavailable'+'subquantity'));**
But it throws error as below:
"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"syntax error, unexpected '=>'"
Does any one have solution?
You were very close with your fluent attempt, but there were two issues:
The plus sign needs to be inside the quotes, since you want the math done in SQL, not in PHP.
Need a DB::raw() around the value so Laravel doesn't think you're actually trying to set it to the string "currentavailable + subquantity"
So the final product looks like this:
DB::table('purchase_stock')
->join('stock', 'stock.stockid', '=', 'purchase_stock.fkstockid')
->where('fkorderid', $orderId)
->update(['currentavailable' => DB::raw('currentavailable + subquantity')]);
Мaybe you need to set these two fields from which tables. Exampl. DB::table('purchase_stock')->join('stock','stock.stockid','=','purchase_stock.fkstockid')->where('fkorderid',$orderId)->update(array('stock.currentavailable'=>'stock.currentavailable'+'stock.subquantity'));
Ohk!
I already tried this one but it is not working
As of now I am using DB::statement('') and it's working
So I have written whole update query within statement and it's working as somewhere I have read that it will not be helpful to return result set but will work with insert or update.

How do I use CONCAT_WS together with IN?

Using Symfony2 and Doctrine2, want to combine CONCAT_WS with IN, rather than write a lot of IF's.
WHERE CONCAT_WS('-', id2, id2) IN ($ids)
I am receiving this error:
[Syntax Error] line 0, col 446: Error: Expected Doctrine\\ORM\\Query\\Lexer::T_IN, got '('
$ids are in form of '123-456'.
If I simply use a column instead of CONCAT_WS, it works:
WHERE id2 IN ($ids)
Not all MySQL functions are available for use in Doctrine. Only those functions that are common to all databases supported are available.
Follow this link to see the list of functions available by default http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#functions-operators-aggregates .
If you want to use CONCAT_WS anyway, read about creating custom functions on the following links. You can create your own DQL Custom Function and will be able to use just like you tried before.
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/dql-user-defined-functions.html
http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html
I've had the same problem as this, I solved it using this:
CONCAT(CONCAT('-', id2), id2)
Not the most elegant solution but it works. Writing a custom function is the way to go.

Why does CakePHP use this method name in a MySQL query rather than return the result?

In applying the answer from a previous question, I tried overriding one of CakePHP's built-in pagination methods:
function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
if (isset($extra['group'])) {
for ($i=0; $i<count($extra['group']);$i++) {
if (strpos(strtolower($extra['group'][$i]),'having')!==false) unset($extra['group'][$i]);
}
exit();
}
$count = parent::paginateCount($conditions, $recursive, $extra);
return $count;
}
The problem is that this seems to cause Cake to do a MySQL query consisting simply of the name of the method. Obviously this doesn't work and throws an error:
SQL Error: 1064: 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 'paginateCount' at line 1
Since I have debugging enabled, I can see that where there would normally be the paginateCount() query:
1: SELECT COUNT(*) AS `count` FROM `tournaments` AS `Tournament` WHERE 1 = 1
I just get:
1: paginateCount
I've obviously misunderstood PHP's inheritance operators. My function seems to be returning the name of the function it is overriding rather than it's value.
How can I fix this?
This usually happens when CakePHP can't find the method in the model or attached behaviors.
It then passes the call to the datasource (hoping it has the method and knows what to do) and that's why you get this error.
I would check things are what they seem (is the method in the right model, is Cake making an automodel because of incorrect filenaming, etc.)
I've fixed this without really addressing the question I asked.
Instead of passing the adjusted parameters up the chain as I wanted to do in my above example, I've used them to do the same job directly:
return $this->find('count', compact($conditions, $recursive, $extra));
This works OK, but doesn't explain the odd behaviour that caused me to ask the question in the first place. My guess is that Cake is doing something funky with virtual/"automagic" methods.

Categories