I run the below query, if cause true then where cause is apply like below, but when i run below query it gives me "Out of memory (allocated 503316480) (tried to allocate 492834816 bytes)" error, So another easy way to check the where cause above if condition.
Here below is my code.
$user_id = "";
$doctor_id = "";
$start_date = "";
$end_date = "";
if(isset($request->user_id)) {
$user_id = $request->user_id;
}
if(isset($request->doctor_id)) {
$doctor_id = $request->doctor_id;
}
if(isset($request->start_date)) {
$start_date = $request->start_date;
}
if(isset($request->end_date)) {
$end_date = $request->end_date;
}
$query = DB::table('request_approves')
->join('city_masters', 'request_approves.city_id', '=', 'city_masters.id')
->join('doctors', 'request_approves.doctor_id', '=', 'doctors.id')
->select('doctors.*','city_masters.*','request_approves.*');
if($user_id !== "") {
$query->where('request_approves.user_id', 2);
}
if($doctor_id !== "") {
$query->where('request_approves.doctor_id',3);
}
if($start_date !== "" & $end_date !==""){
$query->whereBetween('request_approves.approve_time', array($start_date,$end_date));
}
$query->get();
Not sure what it is happening, but your code seems wrong to me .
On the if statements you do something like this $query->where('request_approves.user_id', 2); but where this returned values go ? To continue the same query you should do it like this:
$query = DB::table('request_approves')
->join('city_masters', 'request_approves.city_id', '=', 'city_masters.id')
->join('doctors', 'request_approves.doctor_id', '=', 'doctors.id')
->select('doctors.*','city_masters.*','request_approves.*');
if($user_id !== "") {
$query = $query->where('request_approves.user_id', 2);
}
if($doctor_id !== "") {
$query = $query->where('request_approves.doctor_id',3);
}
if($start_date !== "" & $end_date !==""){
$query = $query->whereBetween('request_approves.approve_time', array($start_date,$end_date));
}
$query = $query->get();
PHP uses memory to perform queries as well. So performing queries from a PHP application will indeed use more memory than performing them straight from MySQL.
I did a simple calculation and 503316480 bytes comes out to 503MB. So I would suggest modifying your php.ini settings. This should let you output data, and from there you can tune your SQL.
In your php.ini
memory_limit=503M
Related
I have composed a query using Codeigniter's Query Builder class. The query utilizes aliases and the having method. When I call the count_all_results method on this query, an exception occurs. Inspecting the log, I see that the query has stripped out the 'having' clauses. Is there a way to keep these clauses in while calling count_all_results? Thanks for your help.
EDIT: I first believed the problem was knowledge-based and not code-based and so did not share the code, but here it is. Please let me know if more is needed.
Here's the call on the model in the controller.
$where_array = array(
$parent_key.' is not NULL' => null
);
$search_post = $request_data['search'];
if (isset($request_data['filter'])) {
$filter_array = $request_data['filter'];
foreach ($filter_array as $filter_pair) {
if (isset($filter_pair['escape'])) {
$where_array[$filter_pair['filterBy']] = null;
} else {
if ($filter_pair['filterBy'] == 'table3_id') {
$where_array['table3.'.$filter_pair['filterBy']] = isset($filter_pair['filterId']) ?
$filter_pair['filterId'] : null;
} else {
$where_array[$table.'.'.$filter_pair['filterBy']] = isset($filter_pair['filterId']) ?
$filter_pair['filterId'] : null;
}
}
}
}
$like_array = array();
foreach ($request_data['columns'] as $key => $column) {
if (!empty($column['search']['value'])) {
$like_array[$column['data']] = $column['search']['value'];
}
}
$totalFiltered = $this->$model_name->modelSearchCount($search, $where_array, $like_array);
Here's the model methods.
public function modelSearchCount($search, $where_array = null, $like_array = null)
{
$this->joinLookups(null, $search);
if ($where_array) {
$this->db->where($where_array);
}
if ($like_array) {
foreach($like_array as $key => $value) {
$this->db->having($key." LIKE '%". $value. "%'");
}
}
return $this->db->from($this->table)->count_all_results();
}
protected function joinLookups($display_config = null, $search = null)
{
$select_array = null;
$join_array = array();
$search_column_array = $search ? array() : null;
$i = 'a';
$config = $display_config ? $display_config : $this->getIndexConfig();
foreach ($config as $column) {
if (array_key_exists($column['field'], $this->lookups)) {
$guest_model_name = $this->lookups[$column['field']];
$this->load->model($guest_model_name);
$join_string =$this->table.'.'.$column['field'].'='.$i.'.'.
$this->$guest_model_name->getKey();
$guest_display = $this->$guest_model_name->getDisplay();
if ($search) {
$search_column_array[] = $i.'.'.$guest_display;
}
$join_array[$this->$guest_model_name->getTable().' as '.$i] = $join_string;
$select_array[] = $i.'.'.
$guest_display;
} else {
$select_array[] = $this->table.'.'.$column['field'];
if ($search) {
$search_column_array[] = $this->table.'.'.$column['field'];
}
}
$i++;
}
$select_array[] = $this->table.'.'.$this->key;
foreach ($join_array as $key => $value) {
$this->db->join($key, $value, 'LEFT');
}
$this->db->join('table2', $this->table.'.table2_id=table2.table2_id', 'LEFT')
->join('table3', 'table2.table3_id=table3.table3_id', 'LEFT')
->join('table4', $this->table.'.table4_id=table4_id', 'LEFT')
->join('table5', 'table4.table5_id=table5.table5_id', 'LEFT');
$this->db->select(implode($select_array, ', '));
if ($search) {
foreach (explode(' ', $search) as $term) {
$this->db->group_start();
$this->db->or_like($this->table.'.'.$this->key, $term);
foreach ($search_column_array as $search_column) {
$this->db->or_like($search_column, $term);
}
$this->db->group_end();
}
}
$this->db->select('table2_date, '. $this->table.'.table2_id, table4_id, '. 'table5.table5_description');
}
Since count_all_results() will basically run a Select count(*) and not count the rows in your resultset (basically rendering the query useless for your purposes) you may use other Codeigniter methods to get the resultset and the row count.
Try running the query into a variable:
$query = $this->db->get();
From then, you can do pretty much anything. Besides returning the result with $query->result(); you can get the number of rows into another variable with:
$rownum = $query->num_rows();
You can then return that into your controller or even just return the $query object and then run the num_rows() method on the controller
To answer this question, count_all_results() transforms the original query by replacing your selects with SELECT COUNT(*) FROM table. the aliased column would not be selected, and the having clause would not recognize the column. This is why count_all_results() does not work with having.
Is the below code safe from SQL injection?
if ($request->has('sort')) {
$s = $request->sort;
if ($request->has('asc')) {
$a = $request->asc;
} else {
$a = 'asc';
}
$query->orderByRaw("ISNULL({$s}), {$s} " . $a);
}
No. As the name suggests, it inserts a raw expression. That is, unsanitized.
If you’re wanting to sort a query, just sort when the require query string parameter(s) are provided:
if ($sort = $request->query('sort')) {
$direction = $request->query('direction');
if (! in_array($direction, ['asc', 'desc'])) {
$direction = 'asc'; // default direction
}
$query->orderBy($sort, $direction);
}
The problem with RAW queries are much more in the bindings (user data) than in the sql query itself, that's why you should avoid them. But it is safer if you add the bindings separately:
public function orderByRaw($sql, $bindings = []) {...}
There is a better approach to achieve this kind of conditional query using when for example:
// You have the $query instance already...
$sort = $request->get('sort');
$query->when($sort, function($query) use($request) {
$order = $request->asc ?: 'asc';
return $query->orderBy($sort, $order);
});
Now, the orderBy will be applied only when the $sort is available and you can add more query constrains further and execute it like:
// $query->where(...);
$result = $query->get();
I am calling URL with search params which are dynamic. How could I form proper Eloquent query?
In theory:
query
query where(someParam1)
query where(someParam2)
query orderby(someParam3)
query get
I need this kind of structure so I can use where clause if param exists.
If there is some other way in Laravel, please let me know.
It's easy with Laravel. Just do something like this:
$query = User::query();
if ($this == $that) {
$query = $query->where('this', 'that');
}
if ($this == $another_thing) {
$query = $query->where('this', 'another_thing');
}
if ($this == $yet_another_thing) {
$query = $query->orderBy('this');
}
$results = $query->get();
You can just use the where statement.
For ex: on users table or User model, you want dynamic search on name, id. You can do this
$where = [];
$firstName = $request->get('first_name');
if ($firstName) $where[] = ['first_name', 'like'. '%' . $firstName . '%'];
$id = $request->get('id');
if ($id) $where[] = ['id', $id];
$users = User::where($where)->get();
By default, it will return all the users, if anything exists in $where array, it will apply the where condition on that.
You can use like this
$validateUserDetail = User::query();
if (!empty($userDetails['email'])) {
$validateUserDetail->whereemail($userDetails['email']);
}if (!empty($userDetails['cellphone'])) {
$validateUserDetail->wherecellphone($userDetails['cellphone']);
}
$validateUserDetail->select('username');
$validateUserDetail->get()
You can pass dynamic value by below example
$user_auctions = $this->with('userAuctions')
->where('users.id', '=', $id)
->get();
I came here from Google. If you are going to be iterating over more then 5 if statements, its more effective to use a switch statement
if(empty($request->except('_token')))
return 'false';
$models = Vehicle::query();
$request_query = $request->all();
$year_switch = false;
foreach ($request_query as $key => $field_value){
if($field_value != 'any'){
switch($field_value){
case 'X':
case 'Y':
$year_switch = true;
break;
case'Z':
//Dynamic
$models->where($key,'LIKE', $field_value);
break;
}
}
}
You can pass a callback to the where function.
So, you can do something like this:
class TestService {
TestRepository $testeRepository;
public function __construct(TesteRepository $teste) {
$this->testeRepository = $teste;
}
public function getAll(array $filters)
{
$where = function (Builder $query) use ($filters) {
collect($filters)
->each(function ($value, $param) use ($query) {
if ($param === 'test') {
$query->where($param, '=', $value);
} else if ($param === 'test2') {
$query->orWhere($param, '>', $value);
}
});
};
return $this->testRepository->gelAll($where);
}
class TestRepository
{
public function getAll(\Closure $where)
{
$query = TestModel::query();
$query->where($where);
//and put more stuff here, like:
//$query->limit(15)->offset(30)
...
return $query->get();
}
}
And in your controller you pass the filters:
class TestControler ...
{
public function $index()
{
$filters = request()->query();
return $this->testService->getAll($filters);
}
}
I am trying to use AND as well as && in this code block:
public function show($id)
{
$user = Auth::user()->id;
$userEmail = Auth::user()->email;
$share = Share::where('sbj_id', $id)->first();
if ($share->sbj_id == $id && $share->email == $userEmail ) {
$items = Item::where('project_id', $id)
->orderBy("created_at", "desc")
->groupBy('label_name')
->get();
$sbj = Sbj::find($id);
$allSbj = Sbj::where('user_id', $user)->orderBy("created_at", "desc")->get();
$labels = Label::all();
$pages = Page::where('project_id', $id)->orderBy('created_at', 'desc')->get();
$people = Friend::where('sbj_id', $id)->orderBy("created_at", "desc")->get();
$myPeeps = Contact::where('my_id', $user)->get();
return View::make('sbjs.show', compact('sbj', 'pages', 'labels', 'people', 'myPeeps', 'allSbj', 'items'));
} else {
return Redirect::action ('SbjsController#index');
}
}
However, I am looking online to see if && or AND is supported in Lavavel in this context but no success. My app is taking the user to the ELSE action.
Any ideas?
I just added the Eloquent statement to the IF conditional and it worked fine...not sure why it was not evaluating.
I basically can’t get the pagination bit to work, I did before I changed my database query and now I’m stuck.
My model looks like:
function get_properties($limit, $offset) {
$location = $this->session->userdata('location');
$property_type = $this->session->userdata('property_type');
if($property_type == 0)
{
$sql = "SELECT * FROM properties ";
}
// more queries here
$sql .= " LIMIT ".$limit.", ".$offset.";";
$query = $this->db->query($sql);
if($query->num_rows() > 0) {
$this->session->set_userdata('num_rows', $query->num_rows());
return $query->result_array();
return FALSE;
}
}
}
and my controller looks like:
function results() {
$config['base_url'] = base_url().'/properties/results';
$config['per_page'] = '3';
$data['properties_results'] = $this->properties_model->get_properties($config['per_page'], $this->uri->segment(3));
$config['total_rows'] = $this->session->userdata('num_rows');
$this->pagination->initialize($config);
$config['full_tag_open']='<div id="pages">';
$config['full_tag_close']='</div>';
$data['links']=$this->pagination->create_links();
$this->load->view('properties_results',$data);
}
please help…its screwing up!
The reason it's not working is that you never get the total_rows. You get the total_rows via this query, but it already has an offset and a limit:
$sql .= " LIMIT ".$limit.", ".$offset.";";
$query = $this->db->query($sql);
To fix this you should add a function to your model:
function get_all_properties()
{
return $this->db->get('properties');
}
Then in your controller, instead of:
$config['total_rows'] = $this->session->userdata('num_rows');
Do:
$config['total_rows'] = $this->properties_model->get_all_properties()->num_rows();
This should fix your pagination. Other than this your code has some strange things. E.g. return FALSE; in get_properties will NEVER execute. And why are you storing so much data in sessions. This is not necessary and not a good idea in my opinion.