Write a query manually into the laravel - php

I have a little problem, I want to try to take the data with a custom query on laravel but when I try foreach I can't get the data. anyone can help me
This script on the controller :
$data = DB::Statement('SELECT NM_PERUSAHAAN,
count(*) as total_count,
sum(FLAG_TERIMA) as approved,
sum(1 - FLAG_TERIMA) as not_approved
from MSTBEASISWAS
group by NM_PERUSAHAAN;');
foreach ($data as $datas) {
echo $datas;
}
Error :

Here is the difference
DB::raw()
It generates a raw and sanitized SQL string, to be passed to other query/statements, preventing SQL injections. Is to be used with all of the and never alone. And you should never send a not sanitized string to your query/statements.
DB::select(DB::raw('select * from whatever'));
DB::select()
Is for simple selects:
DB::select(DB::raw('select * from whatever'));
DB::statement()
I think it work with selects, but should be used for non SQL query commands:
DB::statement(DB::raw('update whatever set valid = true;'));
DB::unprepared()
All SQL commands in Laravel are prepared by default, but sometimes you need to execute a command in an unprepared mode, because some commands in some database cannot be ran in prepared mode. Here's an issue I opened about this:
https://github.com/laravel/framework/issues/53
DB::unprepared(DB::raw('update whatever set valid = true;'));
Ref: Difference between Laravel's raw SQL functions

The DB::statement() method is used to execute SQL statements without returning result instead return true/false.
You're trying to use this boolean as a query result that why you've this message back from the foreach loop, if you want to run a select statement, you could use DB::select(), e.g :
DB::select('select query here');
Hope this helps.

You can write custom query like:
$data = DB::select(DB::raw('your query here'));

You can do as follows :
$data = DB::select($your_select_query);

The "statement" method of the DB facade returns a boolean value, which tells you whether the query execution was successful or not. Therefore foreach can not process it and throws an exception.
You can understand this by looking at the 2nd line of the exception stack trace.
array('data' => true)
So, to run a raw query string use the following code:
DB::select(DB::raw('SELECT NM_PERUSAHAAN,
count(*) as total_count,
sum(FLAG_TERIMA) as approved,
sum(1 - FLAG_TERIMA) as not_approved
from MSTBEASISWAS
group by NM_PERUSAHAAN;'));

DB::statement will not return data. if you are performing queries which don't return data, then using a SELECT query will result errors. For example, if you want to start the auto-increment ID of a MySQL table to something other than zero, we can use the statement method.
for the above query you have to use DB::select.
$data=DB::Statement('SELECT NM_PERUSAHAAN,
count(*) as total_count,
sum(FLAG_TERIMA) as approved,
sum(1 - FLAG_TERIMA) as not_approved
from MSTBEASISWAS
group by NM_PERUSAHAAN;');

Related

What is meant by whereRaw in PHP Laravel framework

I'm unsure what whereRaw is in PHP Laravel framework. Could you provide good and easily understandable example, please?
WhereRaw() is a function of Laravel query builder which puts your input as it is in the SQL query's where clause.
Think of it as the where() function whose input argument will not be processed before inserting into queries.
See the example below:
$Query = DB::table('some_table')->where('YEAR(date)', 'YEAR(CURRENT_DATE)');
In this Laravel will resolve your arguments to build a query. Which will result in the following query because your input will be treated as some field and its its value :
SELECT * FROM `some_table` WHERE `YEAR(date)` = `YEAR(CURRENT_DATE)`
Which is not desired.
And now if you use whereRaw like:
$Query = DB::table('some_table')->whereRaw('YEAR(date) = YEAR(CURRENT_DATE)');
Now Laravel put this where clause as it is in your query, like below:
SELECT * FROM `some_table` WHERE YEAR(date) = YEAR(CURRENT_DATE)
Hope it helped (:
WhereRaw: Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings.
If you are unable to generate the query you need via the fluent interface, feel free to use whereRaw()
Ex:
$users = User::whereRaw('age > ? and votes = 100', array(25))->get();
which is equals to:
"SELECT * FROM users WHERE age > 25 AND votes = 100";
Reference
In laraval we use query builder. But Sometime you need to execute raw sql query.
So you can inject it to whereRaw as this example :
whereRAW('YEAR(event_datetime) =?', [$year])

Eloquent whereRaw statement and orWhereRaw is NULL

For a search query I have the following:
DB::whereRaw('column = ?', 'foo')->orWhereRaw('column IS NULL')->get();
Adding the orWhereRaw statement gives me less results than only the whereRaw. Somehow it seems to ignore the first when adding the other. It is included in the SQL statement. Is there another way to compare for a string and null value?
I have also tried the following, as suggested below:
return self::select('id')
->where('current_state', 'unavailable')
->orWhereNull('current_state')
->get();
If I change the order (the whereNull first and the where second) this also gives me different results. It appears as if the inclusive query doesn't function correctly in correspondence with the where clause. If I use to regular where clauses I don't experience any issues.
Running SELECT * FROM events WHERE current_state='unavailable' OR current_state IS NULL; does produce the correct result for me.
Don't use whereRaw to check for null. You can use this instead:
->orWhereNull('column')
The proper way to do the first where, unless you're doing something extra such as a mysql function, is just to pass the column along like this:
where('column', '=', 'foo')
You can actually eliminate the equals, since it defaults to that. So your query would be:
DB::table('table')->where('column', 'foo')->orWhereNull('column')->get();

SQL OR not returning all rows

I'm having what may be the dumbest issue.
I'm using phpmyadmin and when I query a table using OR it does not return all values.
This is the query that is not returning all values:
SELECT * FROM ecrdatabase.ecrtable m WHERE m.ecrChangeOwner = '$partialOwner' OR m.ecrInitByName = '$partialOwner'.
Here, $partialOwner is passed from $_GET['user'].
Some of the rows are returned - just not all of them. I have a php page that queries the database and I have tried running the query directly on the database through phpmyadmin using query:
SELECT * FROM ecrtable WHERE ecrChangeOwner = 'ecunningham' OR ecrInitByName = 'ecunningham'.
Both results from the the direct query and php page return the same number of rows.
I have also tried:
SELECT * FROM ecrtable WHERE (ecrChangeOwner = 'ecunningham' OR ecrInitByName = 'ecunningham').
What am I missing? I have more complex queries that run fine. Please tell me I'm just missing something stupid...
You really should be using prepared statements here, first of all. You are wide open to injection attacks.
Second, how do you know that this query does not return all the rows? What queries have you done to verify that this one is wrong?
If you run a union what do you get:
SELECT * FROM ecrtable WHERE ecrChangeOwner = 'ecunningham'
UNION ALL
SELECT * FROM ecrtable WHERE ecrInitByName = 'ecunningham')

RedBeanPHP fetchAll only returning one row

I am making a call to the database to fetch some data. I have tried the request in SQL, and it works fine. I have coded the query using PDO, and it works fine. But using RedBeanPHP with the same query only returns one result.
$app->get('/shoutbox/new/:msgid', function ($msgid) use ($app) {
$messages = R::findAll('shoutbox_message', ' WHERE message_id > ? LIMIT 10', array($msgid));
$app->response()->header('Content-Type', 'application/json');
var_dump($messages);
echo json_encode(R::exportAll($messages));
});
I have used var_dump($messages) to verify there's only one message being returned.
I found a similar problem here, but the OP solved it without explaining how: sql query using redbeans php
Any advice?
You are using R::findAll which is used for when you do not want to add any conditions. However, you have a WHERE condition in your query. You want to use the R::find method instead.
I'm not sure what value is being passed is in your $msgid parameter or what the resulting $messages should contain, but the query would look like this.
$messages = R::find('shoutbox_message', ' message_id = ? LIMIT 10', array($msgid) );

how to get the where clause in string format using CakePHP3 ORM?

In CakePHP3, there is a ORM that helps with building queries.
From the documentation, I can see that
$query = $articles->find(); // build a query that has not run yet
$query->where(['id' => 1]); // Return the same query object
So in this case, I want the string
WHERE `articles`.`id` = 1
After much googling, I found out that there is a way to return just the where clause of a query object.
$query->where(['id' => 1])->clause('where'); // Return the where clause in the form of a QueryExpression
More googling leads me to find out how to get the QueryExpression to spit out string representation
$query->where(['id' => 1])->clause('where')->sql($valueBinder); // Return the where clause in string format
Here is my problem. I don't know what the $valueBinder is supposed to look like. I don't know how to initialize it.
I am also happy not to use ValueBinder as long as I can get the where clause in string format using CakePHP 3 ORM and in the right SQL dialect. Please assume I am using MySQL.
Please advise.
EDIT
I tried to use $query->valueBinder() as the $valueBinder.
It is empty and does not contain the associated c:0 to the value 1.
To directly answer your question, you can get the SQL for any clause this way:
$binder = new \Cake\ORM\ValueBinder();
$query->clause('where')->sql($binder);
That will return the SQL with the correct placeholders, not with the values to be used. The values live in the $binder variable and are used for statement objects.
As I can see, you only wanted to preserve the internal structure of the where clause to pass it to another query in a different request. Your solution is fine, but I'd like to add that you can also encode a full conditions tree from an existing query:
$where = serialize($query->clause('where'));
$anotherQuery->where(unserialize($where)); // A query in another request
In any case, you need to be careful with what you are unserializing as taking it directly from user input will certainly lead to security problems.
You can choose to omit this param if you like. Please see http://api.cakephp.org/3.0/class-Cake.Database.Query.html#_sql
In addition, you can use the Query member function traverse($visitor, $parts) to isolate the where clause. $visitor is a function that takes a value and a clause. You define the behavior of $visitor. $parts is an array of clause names. I suggest passing array('where') into this param.
My workaround is that I store the conditions in json string format.
Using the same example, what I do is
$data['conditions'] = json_encode(['Articles.id' => 1]); // encode into JSON string
$this->DynamicRules->patchEntity($dynamicRule, $data); // use in edit action of DynamicRulesController
then when I need to reuse the conditions, I do:
$articlesTable = TableRegistry::get('Articles');
$query = $articlesTable->find(); // new query for Articles
$rule = json_decode($dynamicRule->conditions, true); // get back the conditions in associative array format
$query->where($rule); // re-assign the conditions back
This got me what I ultimately wanted.

Categories